You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xfinium如何使用PdfFlowDocument生成不同方向的PDF

Xfinium PdfFlowDocument 自定义页面方向与内容缩放实现

实现核心是通过分页符单独指定单页参数,不要依赖全局文档设置控制方向,否则所有页面会被统一成同一个方向。

  • 页面方向控制:每添加一页内容前先插入PdfFlowPageBreak,单独给分页符设置PageSize和PageOrientation属性,即可实现单页独立方向,不会影响前后页面
  • 内容缩放:根据目标页面扣除页眉、页脚、边距后的可用区域,按等比规则计算缩放系数,直接赋值给流内容的Scale属性即可,不需要手动写坐标变换
  • 方向旋转:如果提取的原始页面内容方向和目标页方向不匹配,直接设置流内容的Rotation属性为对应角度(0/90/180/270)即可,控件会自动处理坐标偏移,不需要手动计算旋转矩阵

可直接参考以下实现代码:

// 初始化流文档,绑定全局页眉页脚
PdfFlowDocument flowDocument = new PdfFlowDocument();
// 替换为实际的页眉页脚对象
// flowDocument.HeadersFooters.EvenPagesHeader = docHeader;
// flowDocument.HeadersFooters.OddPagesHeader = docHeader;
// flowDocument.HeadersFooters.EvenPagesFooter = docFooter;
// flowDocument.HeadersFooters.OddPagesFooter = docFooter;

// 基础页面参数(以A4纸为例,单位为PDF默认的pt)
const float PortraitWidth = 595f;
const float PortraitHeight = 842f;
const float MarginLeft = 40f;
const float MarginRight = 40f;
const float MarginTop = 50f; // 预留页眉高度
const float MarginBottom = 50f; // 预留页脚高度

// 加载源PDF文件
using FileStream sourceStream = File.OpenRead("你的源PDF文件路径.pdf");
Xfinium.Pdf.Core.PdfFile sourceFile = new Xfinium.Pdf.Core.PdfFile(sourceStream);
Xfinium.Pdf.Graphics.PdfPageContent[] pageContents = sourceFile.ExtractPageContent(0, sourceFile.PageCount - 1);

// 遍历页面内容,索引从0开始对应文档第1页
for (int pageIndex = 0; pageIndex < pageContents.Length; pageIndex++)
{
    Xfinium.Pdf.Graphics.PdfPageContent rawContent = pageContents[pageIndex];
    // 先插入分页符,指定当前页的方向和尺寸
    PdfFlowPageBreak pageBreak = new PdfFlowPageBreak();
    // 按规则设置:第4页(对应索引3)为横向,其余为纵向
    if (pageIndex == 3)
    {
        pageBreak.PageSize = new Xfinium.Pdf.Graphics.PdfSize(PortraitHeight, PortraitWidth);
        pageBreak.PageOrientation = Xfinium.Pdf.PdfPageOrientation.Landscape;
    }
    else
    {
        pageBreak.PageSize = new Xfinium.Pdf.Graphics.PdfSize(PortraitWidth, PortraitHeight);
        pageBreak.PageOrientation = Xfinium.Pdf.PdfPageOrientation.Portrait;
    }
    flowDocument.AddContent(pageBreak);

    // 计算当前页扣除边距、页眉页脚后的可用绘制区域
    float availableWidth = pageBreak.PageSize.Width - MarginLeft - MarginRight;
    float availableHeight = pageBreak.PageSize.Height - MarginTop - MarginBottom;

    // 初始化流内容对象
    var flowContent = new Xfinium.Pdf.FlowDocument.PdfFlowFormXObjectContent(rawContent);
    
    // 计算等比缩放系数,保证内容完整显示不裁切、不变形
    float scaleX = availableWidth / rawContent.Width;
    float scaleY = availableHeight / rawContent.Height;
    flowContent.Scale = Math.Min(scaleX, scaleY);

    // 若原始内容方向和目标页方向不匹配,取消下一行注释设置旋转角度即可
    // flowContent.Rotation = 90;

    // 设置内容边距,避免和页眉页脚重叠
    flowContent.Margins = new Xfinium.Pdf.FlowDocument.PdfFlowContentMargins(
        MarginLeft,
        MarginTop,
        MarginRight,
        MarginBottom
    );

    flowDocument.AddContent(flowContent);
}

注意事项:

  1. 源PDF如果本身带旋转元数据,PdfPageContent会自动读取原始Rotation属性渲染,不需要额外重复旋转,只有强制切换方向时才需要手动修改旋转值
  2. 如果实际页眉、页脚高度和示例预设的50pt不一致,需要同步调整上下边距值,避免内容和页眉页脚重叠
  3. 等比缩放取宽高缩放比的较小值是为了保证内容完整显示,如果需要铺满页面可以取较大值,但会出现内容裁切

内容的提问来源于stack exchange,提问作者FaceOfIngo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:27:13