IRONSOFTWAREHOME
视频

如何使用Razor在C#中无头地将CSHTML转换为PDF

Curtis Chau
Curtis Chau
Updated: 2026年5月18日

Fluid是一个.NET库(在NuGet上作为Fluid.Core发布,由Sebastien Ros编写,采用MIT许可)实现了Liquid模板语言,为开发者提供了一种灵活的方式来渲染动态模板并将内容与表现逻辑分离。 Fluid在生成动态文本输出时很有效,但它不直接支持PDF生成——开发者必须集成一个额外的PDF库来将HTML输出转换为PDF文档。 这种双库方法带来了复杂性,而许多开发团队都希望消除这种复杂性。

本指南提供了从使用外部 PDF 库的 Fluid(模板化)到IronPDF的完整迁移路径,为评估这一过渡的 .NET 专业开发人员提供了分步说明、代码比较和实用示例。

为什么要从 Fluid(模板化)迁移到 IronPDF.

Fluid 是一个基于 Liquid 的优秀模板引擎,但将其用于 PDF 生成会引入显著的复杂性:

双库依赖: Fluid 只生成 HTML——你需要一个单独的 PDF 库(wkhtmltopdf、PuppeteerSharp 等)来创建 PDF,这使得你的依赖项和维护负担翻倍。

**集成复杂性:**协调两个库意味着管理两套配置、错误处理和更新。 当出现故障时,调试变得更具挑战性。

**Liquid语法学习曲线:**开发人员必须学习Liquid模板语法({{ }}, {% %}),而C#已经内置了强大的字符串处理功能。

**PDF 控制有限:**您的 PDF 输出质量取决于您选择与 Fluid 搭配使用的 PDF 库,而不是专用的渲染引擎。

**调试挑战:**模板生成或 PDF 生成阶段都可能出现错误,这使得故障排除比使用单一集成解决方案更加困难。

线程安全问题:TemplateContext不是线程安全的,需要在并发应用中小心管理。

##IronPDFvs Fluid(模板化):功能比较

了解架构差异有助于技术决策者评估迁移投资:

方面流体 + PDF 库IronPDF
依赖关系2 个以上软件包(Fluid + PDF 库)单个软件包
模板Liquid语法({{ }}C# 字符串插值或 Razor
PDF 生成需要外部库内置 Chromium 引擎
CSS支持取决于 PDF 库带有 Flexbox/Grid 的完整 CSS3
JavaScript语言取决于 PDF 库完全支持 JavaScript
线程安全模板上下文不是线程安全的ChromePdfRenderer 是线程安全的
学习曲线Liquid + PDF 库 APIHTML/CSS(网络标准)
错误处理两个错误源单一错误源

快速入门:从 Fluid 迁移到 IronPDF.

迁移工作可以通过以下基本步骤立即开始。

步骤 1:替换 NuGet 软件包

移除 Fluid 和任何外部 PDF 库:

# Remove Fluid and external PDF library
dotnet remove package Fluid.Core
dotnet remove package WkHtmlToPdf-DotNet  # or whatever PDF library you used
dotnet remove package PuppeteerSharp       # if used
SHELL

安装 IronPDF:

# InstallIronPDF(all-in-one solution)
dotnet add package IronPdf
SHELL

步骤 2:更新命名空间

将Fluid命名空间替换为IronPDF:

// Before (Fluid + external PDF library)
using Fluid;
using Fluid.Values;
using SomeExternalPdfLibrary;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;  // For RenderingOptions

步骤 3:初始化许可证

在应用程序启动时添加许可证初始化:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

代码迁移示例

将基本 HTML 转换为 PDF.

最基本的操作揭示了这些方法之间的关键区别。

流畅的方法:

// NuGet: Install-Package Fluid.Core
using Fluid;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse("<html><body><h1>Hello {{name}}!</h1></body></html>");
        var context = new TemplateContext();
        context.SetValue("name", "World");
        var html = await template.RenderAsync(context);
        
        // Fluid only generates HTML - you'd need another library to convert to PDF
        File.WriteAllText("output.html", html);
    }
}

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var html = "<html><body><h1>Hello World!</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}

Fluid需要创建一个SetValue(),异步渲染以获取HTML,然后写入文件——这仍然不是PDF。 代码中的注释明确指出 "Fluid 只能生成 HTML - 您需要另一个库来转换为 PDF"。

IronPDF消除了这种复杂性:创建一个渲染器,调用RenderHtmlAsPdf(),直接保存为PDF。 无中间 HTML 文件,无附加库。

有关 HTML 转 PDF 的高级应用场景,请参阅 HTML 转 PDF 指南

带动态数据的发票模板

带有多个变量的文档模板可以清楚地显示模板模式的差异。

流畅的方法:

// NuGet: Install-Package Fluid.Core
using Fluid;
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse(@"
            <html><body>
                <h1>Invoice #{{invoiceNumber}}</h1>
                <p>Date: {{date}}</p>
                <p>Customer: {{customer}}</p>
                <p>Total: ${{total}}</p>
            </body></html>");
        
        var context = new TemplateContext();
        context.SetValue("invoiceNumber", "12345");
        context.SetValue("date", DateTime.Now.ToShortDateString());
        context.SetValue("customer", "John Doe");
        context.SetValue("total", 599.99);
        
        var html = await template.RenderAsync(context);
        // Fluid outputs HTML - requires additional PDF library
        File.WriteAllText("invoice.html", html);
    }
}

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var invoiceNumber = "12345";
        var date = DateTime.Now.ToShortDateString();
        var customer = "John Doe";
        var total = 599.99;
        
        var html = $@"
            <html><body>
                <h1>Invoice #{invoiceNumber}</h1>
                <p>Date: {date}</p>
                <p>Customer: {customer}</p>
                <p>Total: ${total}</p>
            </body></html>";
        
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("invoice.pdf");
    }
}

Fluid使用Liquid的context.SetValue()。 注释明确指出"Fluid输出HTML - 需要额外的PDF库。" IronPDF使用标准C#字符串插值($"{variable}")——开发人员已经熟悉的语法——并直接输出至PDF。

探索 IronPDF 教程,了解更多文档生成模式。

使用循环的动态数据

带有集合和循环的模板展示了控制流的差异。

流畅的方法:

// NuGet: Install-Package Fluid.Core
using Fluid;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse(@"
            <html><body>
                <h1>{{title}}</h1>
                <ul>
                {% for item in items %}
                    <li>{{item}}</li>
                {% endfor %}
                </ul>
            </body></html>");
        
        var context = new TemplateContext();
        context.SetValue("title", "My List");
        context.SetValue("items", new[] { "Item 1", "Item 2", "Item 3" });
        
        var html = await template.RenderAsync(context);
        // Fluid generates HTML only - separate PDF conversion needed
        File.WriteAllText("template-output.html", html);
    }
}

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var title = "My List";
        var items = new[] { "Item 1", "Item 2", "Item 3" };
        
        var html = $@"
            <html><body>
                <h1>{title}</h1>
                <ul>";
        
        foreach (var item in items)
        {
            html += $"<li>{item}</li>";
        }
        
        html += "</ul></body></html>";
        
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("template-output.pdf");
    }
}

Fluid使用Liquid的{% for item in items %}...{% endfor %}语法——开发人员必须学习的一种模板语言。 注释指出"Fluid仅生成HTML - 需要单独的PDF转换。" IronPDF使用标准C# foreach 循环——无需学习新语法——直接输出至PDF。

Fluid API 到IronPDF映射参考

这种映射通过显示直接的 API 对应关系来加速迁移:

核心类映射

流体类IronPDF 同等产品
FluidParser不适用
FluidTemplate不适用
TemplateContextC# 对象/字符串
TemplateOptionsRenderingOptions
FluidValue本地 C# 类型
外部 PDF 类ChromePdfRenderer

方法映射

流体方法IronPDF 同等产品
new FluidParser()new ChromePdfRenderer()
parser.Parse(source)不适用
template.RenderAsync(context)renderer.RenderHtmlAsPdf(html)
context.SetValue("key", value)var key = value;

Liquid语法到C#映射

液体语法C# 对等语
{{variable}}$"{variable}"
{% for item in items %}foreach (var item in items)
{% if condition %}if (condition)
{{x |上例}}x.ToUpper()
{{x |date: '%Y-%m-%d'}}x.ToString("yyyy-MM-dd")
{{x |number_with_precision: 2}}x.ToString("F2")

常见迁移问题和解决方案

问题 1:液体语法转换

**Fluid:**使用{% control %}语法。

**解决方案:**替换为 C# 字符串插值和控制流:

// Liquid: {{name | upcase}}
// C#: $"{name.ToUpper()}"

// Liquid: {% for item in items %}{{item}}{% endfor %}
// C#: foreach (var item in items) { html += $"{item}"; }
C#

问题 2:模板上下文变量

**Fluid:**使用context.SetValue("key", value)传递数据。

**解决方案:**使用标准 C# 变量:

// Before (Fluid)
var context = new TemplateContext();
context.SetValue("customer", customerName);

// After (IronPDF)
var customer = customerName;
var html = $"<p>Customer: {customer}</p>";

第 3 期:线程安全

Fluid:TemplateContext不是线程安全的,需要在并发应用中小心管理。

解决方案:ChromePdfRenderer是线程安全的,可以在线程间共享。

// Thread-safe usage
private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

public byte[] GeneratePdf(string html)
{
    var pdf = _renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}

第 4 期:两阶段错误处理

**流畅:**错误可能发生在模板阶段或 PDF 生成阶段。

**解决方案:**IronPDF只有一个错误源:

try
{
    var pdf = renderer.RenderHtmlAsPdf(html);
    pdf.SaveAs("output.pdf");
}
catch (Exception ex)
{
    // Single point of failure—easier debugging
    Console.WriteLine($"PDF generation failed: {ex.Message}");
}

流体迁移核对表

迁移前任务

审核您的代码库,确定所有 Fluid 使用情况:

# Find all Fluid references
grep -r "FluidParser\|FluidTemplate\|TemplateContext\|using Fluid" --include="*.cs" --include="*.csproj" .

# Find Liquid template files
find . -name "*.liquid" -o -name "*.html" | xargs grep -l "{{"
SHELL

记录所有模板:文件位置、使用的变量、循环和条件以及外部 PDF 库配置。

代码更新任务

1.删除 Fluid.Core NuGet 软件包 2.删除外部 PDF 库包 3. 安装IronPDF NuGet包 4. 将命名空间导入从IronPdf 5. 转换$"{variable}" 6. 将{% for item in collection %}转换为C# foreach 7. 将{% if condition %}转换为C# if语句 8.将 Liquid 过滤器转换为 C# 方法(例如,...|upcase.ToUpper()) 9. 用FluidParser 10. 用直接C#变量替换TemplateContext.SetValue() 11.删除外部 PDF 库调用 12.在启动时添加IronPDF许可证初始化功能

迁移后测试

迁移后,验证这些方面:

  • 验证 PDF 输出是否符合预期
  • 测试所有模板变体是否能正确呈现
  • 检查图像和样式是否正确显示
  • 验证分页符是否正确
  • 使用各种数据大小进行测试
  • 性能测试与 Fluid + 外部库
  • 测试并发场景中的线程安全

清理任务

  • 删除.liquid模板文件(如果不再需要)
  • 删除与 Fluid 相关的辅助代码
  • 更新文档
  • 清理未使用的依赖关系

迁移到IronPDF的主要优势

从使用外部 PDF 库的 Fluid(模板化)转向IronPDF具有几个关键优势:

**单包解决方案:**消除对两个库的依赖。IronPDF在一个软件包中同时处理模板制作(通过 HTML/CSS)和 PDF 生成。

**无需学习新语法:**使用标准的 C# 字符串插值和控制流,而不是学习 Liquid 模板语法。

线程安全渲染:TemplateContext,简化了并发PDF生成。

**Chromium渲染引擎:**基于Chromium的渲染支持现代CSS(包括Flexbox和Grid)和JavaScript执行。

**单一错误源:**只需对一个库进行故障排除,而无需在模板和 PDF 生成阶段之间进行协调,从而简化了调试过程。

**广泛的.NET覆盖:**IronPDF支持.NET Framework 4.6.2+、.NET Core 2.0+、.NET Standard 2.0、以及.NET 5到.NET 10。

请注意: Fluid、PuppeteerSharp和wkhtmltopdf是其各自所有者的商标。 本站与这些项目或其维护者没有关联、认可或赞助。 所有产品名称、徽标和品牌均为各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。
Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

...
阅读更多

相关文章

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
预约您的免费现场演示
Booking Badge

深受全球数百万工程师信赖

Iron Software 的客户徽标
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户