Aegis.DocumentConverter 使用指南

Aegis.DocumentConverter 是一个 .NET 文档转换库。当前版本支持将 HTML、Word 文档转换为 PDF 或 OFD 格式。


目录


1. 功能概述

支持的转换类型

转换类型 说明
HTML → PDF 将 HTML 内容转换为 PDF 文档
Word → PDF 将 Word 文档(.doc/.docx)转换为 PDF
PDF → OFD 将 PDF 转换为 OFD(国产版式文档)
HTML → OFD 将 HTML 转换为 OFD(内部自动经 PDF 中转)
Word → OFD 将 Word 转换为 OFD(内部自动经 PDF 中转)

转换器接口

接口 用途
IHtmlToPdfConverter HTML 转 PDF
IWordToPdfConverter Word 转 PDF
IPdfToOfdConverter PDF 转 OFD
IHtmlToOfdConverter HTML 转 OFD
IWordToOfdConverter Word 转 OFD

2. 如何引入

2.1 安装 NuGet 包

文档转换器组件包含在 Aegis.DocumentConverter 的 Nuget 包中。

dotnet add package Aegis.DocumentConverter

2.2 注册服务

确认 Component.deps.json 配置文件的 Services 节点中包含 DocumentConverter

{
    "Components": {
        "Services": [ "DocumentConverter" ]
    }
}

3. 使用示例

3.1 HTML → PDF

public class HtmlToPdfService
{
    private readonly IHtmlToPdfConverter _converter;

    public HtmlToPdfService(IHtmlToPdfConverter converter)
    {
        _converter = converter;
    }

    // 从 HTML 字符串转换
    public async Task<Stream> ConvertFromStringAsync(string htmlContent)
    {
        return await _converter.ConvertAsync(htmlContent);
    }

    // 从 HTML 流转换
    public async Task<Stream> ConvertFromStreamAsync(Stream htmlStream)
    {
        return await _converter.ConvertAsync(htmlStream);
    }

    // 使用自定义选项转换
    public async Task<Stream> ConvertWithOptionsAsync(string htmlContent)
    {
        var options = new HtmlToPdfOptions
        {
            Format = PaperFormats.A4,
            Landscape = false,
            PrintBackground = true,
            MarginTop = "10mm",
            MarginBottom = "10mm",
            MarginLeft = "10mm",
            MarginRight = "10mm"
        };

        return await _converter.ConvertAsync(htmlContent, options);
    }
}

3.2 Word → PDF

public class WordToPdfService
{
    private readonly IWordToPdfConverter _converter;

    public WordToPdfService(IWordToPdfConverter converter)
    {
        _converter = converter;
    }

    public async Task<Stream> ConvertAsync(Stream docStream, DocFormat format)
    {
        return await _converter.ConvertAsync(docStream, format);
    }

    public async Task<byte[]> ConvertFileAsync(string filePath)
    {
        await using var fileStream = File.OpenRead(filePath);

        // 根据扩展名判断格式
        var format = Path.GetExtension(filePath).ToLower() == ".docx" 
            ? DocFormat.Docx 
            : DocFormat.Doc;

        var pdfStream = await _converter.ConvertAsync(fileStream, format);

        using var memoryStream = new MemoryStream();
        await pdfStream.CopyToAsync(memoryStream);
        return memoryStream.ToArray();
    }
}

3.3 PDF → OFD

public class PdfToOfdService
{
    private readonly IPdfToOfdConverter _converter;

    public PdfToOfdService(IPdfToOfdConverter converter)
    {
        _converter = converter;
    }

    // 使用默认页面尺寸
    public async Task<Stream> ConvertAsync(Stream pdfStream)
    {
        return await _converter.ConvertAsync(pdfStream);
    }

    // 指定页面尺寸
    public async Task<Stream> ConvertWithPageSizeAsync(Stream pdfStream, PageSize pageSize)
    {
        return await _converter.ConvertAsync(pdfStream, pageSize);
    }
}

3.4 HTML → OFD

public class HtmlToOfdService
{
    private readonly IHtmlToOfdConverter _converter;

    public HtmlToOfdService(IHtmlToOfdConverter converter)
    {
        _converter = converter;
    }

    // 内部自动执行 HTML → PDF → OFD
    public async Task<Stream> ConvertFromStringAsync(string htmlContent)
    {
        return await _converter.ConvertAsync(htmlContent);
    }

    public async Task<Stream> ConvertWithOptionsAsync(string htmlContent, HtmlToPdfOptions options)
    {
        return await _converter.ConvertAsync(htmlContent, options);
    }
}

3.5 Word → OFD

public class WordToOfdService
{
    private readonly IWordToOfdConverter _converter;

    public WordToOfdService(IWordToOfdConverter converter)
    {
        _converter = converter;
    }

    // 内部自动执行 Word → PDF → OFD
    public async Task<Stream> ConvertAsync(Stream docStream, DocFormat format)
    {
        return await _converter.ConvertAsync(docStream, format);
    }

    // 指定页面尺寸
    public async Task<Stream> ConvertWithPageSizeAsync(Stream docStream, DocFormat format, PageSize pageSize)
    {
        return await _converter.ConvertAsync(docStream, format, pageSize);
    }
}

4. 配置说明

本库提供两类配置:

类型 说明 配置时机
转换选项 控制单次转换的输出结果(页面大小、边距等) 每次调用转换方法时传入
引擎配置 控制引擎的运行行为(并发数、超时等) 应用启动时配置

4.1 转换选项

转换选项在每次调用转换方法时传入,用于控制输出结果。如不传入,将使用框架默认值。

HtmlToPdfOptions

var options = new HtmlToPdfOptions
{
    // 页面设置
    Format = PaperFormats.A4,            // 纸张格式(默认 A4)
    Landscape = false,                    // 纸张方向:false=纵向,true=横向

    // 边距设置(支持单位:mm、cm、in)
    MarginTop = "10mm",
    MarginBottom = "10mm",
    MarginLeft = "10mm",
    MarginRight = "10mm",

    // 内容设置
    PrintBackground = true,               // 是否打印背景(默认 true)
    Scale = 1m,                           // 缩放比例(0.1~2,默认 1)

    // 页眉页脚
    DisplayHeaderFooter = false,          // 是否显示页眉页脚
    HeaderTemplate = "",                  // 页眉 HTML 模板
    FooterTemplate = "",                  // 页脚 HTML 模板

    // 超时设置
    NavigationTimeoutMs = 30000,          // 页面加载超时(默认 30 秒)
    AdditionalWaitTimeMs = 0              // 额外等待时间(用于动态渲染)
};

PageSize

PDF 转 OFD 或 Word 转 OFD 时可指定输出页面尺寸:

var ofdStream = await _pdfToOfdConverter.ConvertAsync(pdfStream, PageSize.A4);

支持的页面尺寸:LetterLegalTabloidLedgerA0~A6

4.2 引擎配置

引擎配置控制底层转换引擎的运行行为,在应用启动时配置一次。

⚠️ 重要提示:框架已为所有引擎参数提供了经过优化的默认值,大多数场景无需修改引擎配置。仅在以下情况才需要调整:

  • 服务器资源与默认配置不匹配(如需要更高并发)
  • 遇到超时问题需要延长等待时间
  • 特殊部署环境需要指定路径

修改前请充分了解各参数含义,并结合实际运行环境评估影响。

引擎配置支持配置文件和代码两种方式。

方式一:配置文件(推荐)

appsettings.json 中配置。框架默认从 DocumentConverter 节点读取各引擎配置:

引擎 配置节点路径 用途
PuppeteerSharp DocumentConverter:PuppeteerSharp HTML → PDF 引擎
UnoServer DocumentConverter:UnoServer Word → PDF 引擎

配置示例:

{
  "DocumentConverter": {
    "PuppeteerSharp": {
      "MaxConcurrency": 2,
      "LaunchTimeoutMs": 60000,
      "AcquireTimeoutMs": 60000,
      "BrowserIdleTimeoutMs": 1800000
    },
    "UnoServer": {
      "MaxConcurrency": 5,
      "ConversionTimeoutSeconds": 300,
      "LibreOfficePath": null
    }
  }
}

💡 使用以上配置节点结构时,框架会自动读取配置,无需在代码中手动绑定。

方式二:代码配置

Program.cs 中通过 Configure<T> 方法配置:

// Program.cs
builder.Services.Configure<PuppeteerSharpOptions>(options =>
{
    options.MaxConcurrency = 2;
    options.LaunchTimeoutMs = 60000;
});

builder.Services.Configure<UnoServerOptions>(options =>
{
    options.MaxConcurrency = 5;
    options.ConversionTimeoutSeconds = 300;
});

PuppeteerSharp 配置参数

用于 HTML → PDF 转换(Chromium 无头浏览器引擎)。

PuppeteerSharpOptions
参数 类型 默认值 说明
AutoStart bool true 是否在应用启动时自动启动 Chromium
Headless bool true 是否使用无头模式(无界面)
MaxConcurrency int 2 最大并发转换数,控制同时处理的请求数
UsePagePool bool false 是否启用页面池模式
LaunchTimeoutMs int 60000 浏览器启动超时(毫秒)
AcquireTimeoutMs int 60000 获取页面超时(毫秒)
BrowserIdleTimeoutMs int 1800000 浏览器空闲后自动关闭时间(30 分钟)
CleanupIntervalMs int 60000 清理检查间隔(毫秒)
DownloadPath string .local-chromium Chromium 下载保存目录
BuildId string 121.0.6167.85 Chromium 版本号
ChinaMirrorUrl string npmmirror 地址 国内镜像源地址(在线环境优先使用)
PagePoolOptions(页面池配置)

UsePagePool = true 时生效,通过 PagePool 属性配置:

参数 类型 默认值 说明
MinInstances int 0 最小页面实例数(启动时预热)
PageIdleTimeoutMs int 180000 页面空闲超时(3 分钟后释放)
MaxLifetimeMs int 1800000 页面最大生存时间(30 分钟后强制释放)

💡 页面池模式:启用后会预创建并复用浏览器页面,适合高频转换场景,可减少页面创建开销。默认关闭,按需创建页面。

UnoServer 配置参数

用于 Word → PDF 转换:

参数 类型 默认值 说明
MaxConcurrency int 5 最大并发转换数
ConversionTimeoutSeconds int 300 单次转换超时(秒)
LibreOfficePath string? null LibreOffice 路径(null=自动检测)
TempDirectory string 系统临时目录 临时文件目录
AutoStart bool true 是否自动启动服务(仅 Linux)
UnoServerHost string 127.0.0.1 服务监听地址(仅 Linux)
UnoServerPort int 2003 服务监听端口(仅 Linux)

💡 UnoServer 引擎会根据操作系统自动选择模式:Windows 使用 Direct 模式直接调用 LibreOffice,Linux 使用 Server 模式通过 unoserver 服务转换。

资源配置建议

服务器配置 PuppeteerSharp MaxConcurrency UnoServer MaxConcurrency
2C2G 2~3 3~5
4C4G 5~8 5~8
8C8G 10~15 10~15

⚠️ Chromium 内存估算:由于使用共享渲染进程模式(--renderer-process-limit=1),内存占用为 基础 250~350MB + 每个并发页面 30~80MB。例如:MaxConcurrency=5 时约需 450~700MB。


5. 环境部署

本库依赖外部运行时组件,部署前需完成环境准备。

📖 完整的安装命令和配置说明请查看 环境准备指南

5.1 依赖项说明

转换功能 依赖项 作用
HTML → PDF Chromium 无头浏览器,用于渲染 HTML 并导出 PDF
Word → PDF LibreOffice 开源办公套件,用于解析 Word 文档并转换为 PDF
PDF → OFD 纯 .NET 实现,无需外部依赖

5.2 在线环境

在可访问外网的服务器上,各依赖项的处理方式如下:

Chromium(HTML → PDF 所需)

  • 首次使用时自动检测系统已安装的 Chrome/Chromium
  • 若未检测到,则自动下载到本地缓存目录
  • 下载时机:AutoStart = true 时在应用启动时触发,否则在首次调用转换时触发
  • 无需手动安装

LibreOffice(Word → PDF 所需)

  • 需手动安装,不支持自动安装
  • Windows:从 官网 下载安装包
  • Linux:通过包管理器安装(apt/yum)

Python + unoserver(仅 Linux 服务器模式)

  • Python:需手动安装(apt install python3 python3-pip
  • unoserver:若 Python 已安装,会自动通过 pip 安装

📖 详细安装命令请参考 环境准备指南

5.3 离线环境

离线环境需提前准备所有依赖项的安装包,根据操作系统参考对应文档:

操作系统 部署文档
Windows Server deploy-offline-windows.md
Debian / Ubuntu deploy-offline-debian.md
RHEL / CentOS deploy-offline-rhel.md

5.4 Docker 部署

详细的 Dockerfile 示例和多阶段构建配置请参阅 deploy-docker.md


6. 注意事项

  1. 并发控制:转换操作消耗较多资源,请根据服务器配置合理设置并发数
  2. 超时设置:复杂文档转换耗时较长,如遇超时请适当调整超时参数
  3. 资源释放:大文档转换时注意内存占用,转换返回的 Stream 使用完毕后应及时 Dispose
  4. 字体支持:确保服务器已安装所需的中文字体,避免输出文档出现乱码

results matching ""

    No results matching ""