最近处理 PDF 文件时遇到一个需求:把已有 PDF 的页面尺寸统一调整一下。有些文件是系统导出的,有些是扫描件,页面大小不一致,后面打印或归档时不太方便。
这里记录一下用 C# 调整 PDF 页面大小的做法。核心思路不是直接改原 PDF 的页面属性,而是重新创建一个 PDF,把原来的每一页作为模板绘制到新页面上。
这样处理后,原页面里的文字、图片、表格等内容都能保留下来,同时可以把页面尺寸改成 A4、A3、A1 这类标准尺寸,也可以改成自己指定的宽高。
示例里用到的是 Spire.PDF。如果是 NuGet 包管理器,可以直接安装:
PM> Install-Package Spire.PDF也可以用 .NET CLI:
dotnet add package Spire.PDF代码中需要引入下面几个命名空间:
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;调整页面大小时,可以按这个流程来做:
先读取原 PDF,然后创建一个新的 PDF。接着遍历原 PDF 的每一页,在新 PDF 里创建目标尺寸的新页面,再把原页面生成模板并绘制到新页面上。
听起来步骤比较多,但代码其实不复杂。这里有一个比较重要的设置:
PdfTextLayout layout = new PdfTextLayout();
layout.Layout = PdfLayoutType.OnePage;这个设置的作用是让原页面内容适配到新页面中。如果不加,在页面尺寸变化比较明显时,内容可能不会按照预期缩放。
如果只是想改成 A4、A3、A1、Letter、Legal 这类常见尺寸,可以直接使用 PdfPageSize。
下面的示例是把原 PDF 的页面统一改成 A1。
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,只需要把这一行:
PdfPageBase newPage = outputPdf.Pages.Add(PdfPageSize.A1, new PdfMargins(0));改成:
PdfPageBase newPage = outputPdf.Pages.Add(PdfPageSize.A4, new PdfMargins(0));常用的尺寸可以这样写:
PdfPageSize.A4
PdfPageSize.A3
PdfPageSize.Letter
PdfPageSize.Legal这里的 new PdfMargins(0) 表示不额外加页边距。如果想让内容四周留一点空白,也可以设置成:
new PdfMargins(20)不过加了页边距以后,实际可绘制区域会变小,页面内容的缩放效果也会受到影响。
如果目标尺寸不是标准纸张,比如要做票据、标签、电子书页面,或者要适配某个固定打印模板,就需要自定义宽高。
Spire.PDF 里页面尺寸的单位是 point。 1 inch = 72 points。
如果你的尺寸是英寸、毫米或厘米,可以先转换成 point,再创建页面。
下面示例把页面尺寸改成 6.5 × 8.5 英寸。
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,可以这样写:
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:
PdfPageBase newPage = outputPdf.Pages.Add(pageSize, new PdfMargins(0));这种方式比手动计算 point 更稳一些,也不容易写错单位。
一开始我也以为改页面大小应该就是修改页面属性。但 PDF 里的内容位置、页面尺寸、坐标系统是关联在一起的。直接改页面尺寸,不一定能让原来的内容自动适配。
所以更稳的做法是:
PdfTemplate template = sourcePage.CreateTemplate();
template.Draw(newPage, new PointF(0, 0), layout);也就是把原页面当成一个整体模板,再画到目标尺寸的新页面上。
配合:
layout.Layout = PdfLayoutType.OnePage;可以让内容尽量缩放到新页面范围内。
不过也要注意,如果原页面和目标页面比例差距太大,最终效果可能会出现比较大的留白,或者内容看起来被压缩。比如把横向页面强行转成竖向 A4,就需要人工检查一下效果。
如果只是为了打印、归档、统一页面规格,优先用标准尺寸就行:
outputPdf.Pages.Add(PdfPageSize.A4, new PdfMargins(0));如果是业务里有明确尺寸要求,比如标签、票据、证书、书籍页面,那就用自定义尺寸:
outputPdf.Pages.Add(pageSize, new PdfMargins(0));实际项目里,我更建议把目标尺寸做成配置项。这样后面要从 A4 改成 A3,或者从英寸改成毫米,不需要改太多代码。
如果项目里会多次用到,可以把逻辑简单封装一下。
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();
}调用时可以这样写:
ResizeToStandardSize("Sample.pdf", "Output.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);
ResizeToStandardSize("Sample.pdf", "Output.pdf", customSize);页面尺寸调整后,最好输出成一个新的 PDF。确认效果没问题后,再决定是否替换原文件。
Sample.pdf
ResizeToA4.pdf这样出问题也能回退。
示例中用了 0 页边距:
new PdfMargins(0)如果设置了页边距,内容区域会变小,缩放后的内容也会跟着变小。这个在打印场景里尤其要注意。
如果批量处理多个 PDF,不要所有输出都叫 Output.pdf。可以在文件名里加上尺寸或时间:
report_A4.pdf
report_A3.pdf
report_custom.pdf程序可以完成页面缩放,但不一定能保证视觉效果一定完美。尤其是下面几种情况:
这类文件建议转换后抽查几页。
最后放一个稍微整理过的完整版本,标准尺寸和自定义尺寸都可以用。
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 页面尺寸不统一的情况。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。