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); }
注意事项:
- 源PDF如果本身带旋转元数据,
PdfPageContent会自动读取原始Rotation属性渲染,不需要额外重复旋转,只有强制切换方向时才需要手动修改旋转值- 如果实际页眉、页脚高度和示例预设的50pt不一致,需要同步调整上下边距值,避免内容和页眉页脚重叠
- 等比缩放取宽高缩放比的较小值是为了保证内容完整显示,如果需要铺满页面可以取较大值,但会出现内容裁切
内容的提问来源于stack exchange,提问作者FaceOfIngo
相关产品推荐
相关产品推荐

