最近处理 PDF 文件时遇到一个需求:把已有 PDF 的页面尺寸统一调整一下
有些文件是系统导出的,有些是扫描件,页面大小不一致,后面打印或归档时不太方便
这里记录一下用 C# 调整 PDF 页面大小的做法
核心思路不是直接改原 PDF 的页面属性,而是重新创建一个 PDF,把原来的每一页作为模板绘制到新页面上
这样处理后,原页面里的文字、图片、表格等内容都能保留下来,同时可以把页面尺寸改成 A4、A3、A1 这类标准尺寸,也可以改成自己指定的宽高
安装 Spire.PDF示例里用到的是 Spire.PDF
如果是 NuGet 包管理器,可以直接安装:代码语言:javascript复制PM> Install-Package Spire.PDF也可以用 .NET CLI:代码语言:javascript复制dotnet add package Spire.PDF代码中需要引入下面几个命名空间:代码语言:javascript复制using Spire.Pdf; using Spire.Pdf.Graphics; using System.Drawing;基本处理思路调整页面大小时,可以按这个流程来做:先读取原 PDF,然后创建一个新的 PDF

接着遍历原 PDF 的每一页,在新 PDF 里创建目标尺寸的新页面,再把原页面生成模板并绘制到新页面上
听起来步骤比较多,但代码其实不复杂
这里有一个比较重要的设置:代码语言:javascript复制PdfTextLayout layout = new PdfTextLayout(); layout.Layout = PdfLayoutType.OnePage;这个设置的作用是让原页面内容适配到新页面中
如果不加,在页面尺寸变化比较明显时,内容可能不会按照预期缩放
一、把 PDF 页面改成标准纸张大小如果只是想改成 A4、A3、A1、Letter、Legal 这类常见尺寸,可以直接使用 PdfPageSize
下面的示例是把原 PDF 的页面统一改成 A1
代码语言:javascript复制using Spire.Pdf; using Spire.Pdf.Graphics; using System.Drawing; namespace ResizePdfToStandardSize { class Program { static void Main(string[] args) { // 读取原始 PDF PdfDocument sourcePdf = new PdfDocument(); sourcePdf.LoadFromFile("Sample.pdf"); // 创建新的 PDF PdfDocument outputPdf = new PdfDocument(); foreach (PdfPageBase sourcePage in sourcePdf.Pages) { // 新建 A1 页面,页边距设置为 0 PdfPageBase newPage = outputPdf.Pages.Add(PdfPageSize.A1, new PdfMargins(0)); // 让原页面内容适配到新页面 PdfTextLayout layout = new PdfTextLayout(); layout.Layout = PdfLayoutType.OnePage; // 把原页面做成模板 PdfTemplate template = sourcePage.CreateTemplate(); // 绘制到新页面 template.Draw(newPage, new PointF(0, 0), layout); } outputPdf.SaveToFile("ResizeToA1.pdf"); sourcePdf.Close(); outputPdf.Close(); } } }如果要改成 A4,只需要把这一行:代码语言:javascript复制PdfPageBase newPage = outputPdf.Pages.Add(PdfPageSize.A1, new PdfMargins(0));改成:代码语言:javascript复制PdfPageBase newPage = outputPdf.Pages.Add(PdfPageSize.A4, new PdfMargins(0));常用的尺寸可以这样写:代码语言:javascript复制PdfPageSize.A4 PdfPageSize.A3 PdfPageSize.Letter PdfPageSize.Legal这里的 new PdfMargins(0) 表示不额外加页边距
如果想让内容四周留一点空白,也可以设置成:代码语言:javascript复制new PdfMargins(20)不过加了页边距以后,实际可绘制区域会变小,页面内容的缩放效果也会受到影响
二、把 PDF 页面改成自定义尺寸如果目标尺寸不是标准纸张,比如要做票据、标签、电子书页面,或者要适配某个固定打印模板,就需要自定义宽高
Spire.PDF 里页面尺寸的单位是 point
1 inch = 72 points
如果你的尺寸是英寸、毫米或厘米,可以先转换成 point,再创建页面
下面示例把页面尺寸改成 6.5 × 8.5 英寸
代码语言:javascript复制using Spire.Pdf; using Spire.Pdf.Graphics; using System.Drawing; namespace ResizePdfToCustomSize { class Program { static void Main(string[] args) { PdfDocument sourcePdf = new PdfDocument(); sourcePdf.LoadFromFile("Sample.pdf"); PdfDocument outputPdf = new PdfDocument(); // 单位转换 PdfUnitConvertor convertor = new PdfUnitConvertor(); float width = convertor.ConvertUnits(6.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point); float height = convertor.ConvertUnits(8.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point); SizeF pageSize = new SizeF(width, height); foreach (PdfPageBase sourcePage in sourcePdf.Pages) { PdfPageBase newPage = outputPdf.Pages.Add(pageSize, new PdfMargins(0)); PdfTextLayout layout = new PdfTextLayout(); layout.Layout = PdfLayoutType.OnePage; PdfTemplate template = sourcePage.CreateTemplate(); template.Draw(newPage, new PointF(0, 0), layout); } outputPdf.SaveToFile("ResizeToCustomSize.pdf"); sourcePdf.Close(); outputPdf.Close(); } } }这个写法适合尺寸来自业务需求的场景
比如设计稿给的是英寸,或者打印规格里写的是固定宽高,都可以先转换成 point 再处理
三、如果尺寸单位是毫米打印类需求里,毫米会更常见
比如想设置成 210mm × 297mm,可以这样写:代码语言:javascript复制PdfUnitConvertor convertor = new PdfUnitConvertor(); float width = convertor.ConvertUnits(210f, PdfGraphicsUnit.Millimeter, PdfGraphicsUnit.Point); float height = convertor.ConvertUnits(297f, PdfGraphicsUnit.Millimeter, PdfGraphicsUnit.Point); SizeF pageSize = new SizeF(width, height);然后创建页面时直接使用这个 pageSize:代码语言:javascript复制PdfPageBase newPage = outputPdf.Pages.Add(pageSize, new PdfMargins(0));这种方式比手动计算 point 更稳一些,也不容易写错单位
四、为什么要用模板重新绘制一开始我也以为改页面大小应该就是修改页面属性
但 PDF 里的内容位置、页面尺寸、坐标系统是关联在一起的
直接改页面尺寸,不一定能让原来的内容自动适配
所以更稳的做法是:代码语言:javascript复制PdfTemplate template = sourcePage.CreateTemplate(); template.Draw(newPage, new PointF(0, 0), layout);也就是把原页面当成一个整体模板,再画到目标尺寸的新页面上
配合:代码语言:javascript复制layout.Layout = PdfLayoutType.OnePage;可以让内容尽量缩放到新页面范围内
不过也要注意,如果原页面和目标页面比例差距太大,最终效果可能会出现比较大的留白,或者内容看起来被压缩
比如把横向页面强行转成竖向 A4,就需要人工检查一下效果
五、标准尺寸和自定义尺寸怎么选如果只是为了打印、归档、统一页面规格,优先用标准尺寸就行:代码语言:javascript复制outputPdf.Pages.Add(PdfPageSize.A4, new PdfMargins(0));如果是业务里有明确尺寸要求,比如标签、票据、证书、书籍页面,那就用自定义尺寸:代码语言:javascript复制outputPdf.Pages.Add(pageSize, new PdfMargins(0));实际项目里,我更建议把目标尺寸做成配置项
这样后面要从 A4 改成 A3,或者从英寸改成毫米,不需要改太多代码
六、封装成一个简单方法如果项目里会多次用到,可以把逻辑简单封装一下
转成标准尺寸代码语言:javascript复制static void ResizeToStandardSize(string inputPath, string outputPath, SizeF targetSize) { PdfDocument sourcePdf = new PdfDocument(); sourcePdf.LoadFromFile(inputPath); PdfDocument outputPdf = new PdfDocument(); foreach (PdfPageBase sourcePage in sourcePdf.Pages) { PdfPageBase newPage = outputPdf.Pages.Add(targetSize, new PdfMargins(0)); PdfTextLayout layout = new PdfTextLayout(); layout.Layout = PdfLayoutType.OnePage; PdfTemplate template = sourcePage.CreateTemplate(); template.Draw(newPage, new PointF(0, 0), layout); } outputPdf.SaveToFile(outputPath); sourcePdf.Close(); outputPdf.Close(); }调用时可以这样写:代码语言:javascript复制ResizeToStandardSize("Sample.pdf", "Output.pdf", PdfPageSize.A4);如果是自定义尺寸,也可以先转换单位:代码语言:javascript复制PdfUnitConvertor convertor = new PdfUnitConvertor(); float width = convertor.ConvertUnits(6.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point); float height = convertor.ConvertUnits(8.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point); SizeF customSize = new SizeF(width, height); ResizeToStandardSize("Sample.pdf", "Output.pdf", customSize);七、几个容易忽略的点1. 不建议直接覆盖原文件页面尺寸调整后,最好输出成一个新的 PDF
确认效果没问题后,再决定是否替换原文件
代码语言:javascript复制Sample.pdf ResizeToA4.pdf这样出问题也能回退
2. 页边距会影响内容大小示例中用了 0 页边距:代码语言:javascript复制new PdfMargins(0)如果设置了页边距,内容区域会变小,缩放后的内容也会跟着变小
这个在打印场景里尤其要注意
3. 批量转换时要注意文件命名如果批量处理多个 PDF,不要所有输出都叫 Output.pdf
可以在文件名里加上尺寸或时间:代码语言:javascript复制report_A4.pdf report_A3.pdf report_custom.pdf4. 页面比例不一致时要人工检查程序可以完成页面缩放,但不一定能保证视觉效果一定完美
尤其是下面几种情况:横向页面转竖向页面;大图纸缩小成 A4;扫描件页面边缘有大量空白;原 PDF 每页尺寸本身不一致
这类文件建议转换后抽查几页
八、完整代码参考最后放一个稍微整理过的完整版本,标准尺寸和自定义尺寸都可以用
代码语言:javascript复制using Spire.Pdf; using Spire.Pdf.Graphics; using System.Drawing; namespace ResizePdfPage { class Program { static void Main(string[] args) { // 示例一:转为 A4 ResizePdf("Sample.pdf", "ResizeToA4.pdf", PdfPageSize.A4); // 示例二:转为自定义尺寸,单位为英寸 PdfUnitConvertor convertor = new PdfUnitConvertor(); float width = convertor.ConvertUnits(6.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point); float height = convertor.ConvertUnits(8.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point); SizeF customSize = new SizeF(width, height); ResizePdf("Sample.pdf", "ResizeToCustomSize.pdf", customSize); } static void ResizePdf(string inputPath, string outputPath, SizeF pageSize) { PdfDocument sourcePdf = new PdfDocument(); sourcePdf.LoadFromFile(inputPath); PdfDocument outputPdf = new PdfDocument(); foreach (PdfPageBase sourcePage in sourcePdf.Pages) { PdfPageBase newPage = outputPdf.Pages.Add(pageSize, new PdfMargins(0)); PdfTextLayout layout = new PdfTextLayout(); layout.Layout = PdfLayoutType.OnePage; PdfTemplate template = sourcePage.CreateTemplate(); template.Draw(newPage, new PointF(0, 0), layout); } outputPdf.SaveToFile(outputPath); sourcePdf.Close(); outputPdf.Close(); } } }结尾整体看下来,调整 PDF 页面尺寸主要就是两件事:第一,确定目标页面大小,是用 A4、A3 这类标准尺寸,还是用自定义宽高
第二,把原 PDF 页面作为模板绘制到新页面上,并设置单页适配
如果只是统一打印尺寸,用 PdfPageSize.A4 这类标准尺寸就够了
如果是特殊业务页面,可以先用 PdfUnitConvertor 把英寸或毫米转换成 point,再创建对应尺寸的页面
实际使用时,建议重点检查输出页面的比例、留白和内容缩放效果,尤其是原 PDF 页面尺寸不统一的情况
标签: PDF转换 技术升级 效率提升