该页面可以包含自动翻译的文本。
在 C# 和 VB.NET 中合并 PDF 文档
企业经常合并 PDF 文件以进行文档存档。虽然 PDF 合并听起来像是一项简单的任务,但这里有很多陷阱。您应该正确组合表单字段、书签、图层和其他 PDF 对象。您还应该避免重复的对象以获得紧凑的输出文件。
Docotic.Pdf 库 处理所有合并细节。它允许您仅用几行 C# 或 VB.NET 代码合并 PDF 文档。
Docotic.Pdf 附带 免费和付费许可证。在 下载 C# .NET PDF 库 页面获取该库和免费限时许可证密钥。
9.6.17807 14,868 通过 NuGet 总下载量 5,134,090PDF 合并基础
PdfDocument.Append 方法允许您从文件、流或字节数组中附加 PDF 文档。还有用于附加受保护文件和合并表单字段的选项。
合并两个 PDF 文件
此示例代码展示了如何在 C# 中合并 PDF 文件:
using var pdf = new PdfDocument("first.pdf");
pdf.Append("second.pdf");
pdf.Save("merged.pdf");
尝试 GitHub 中的 合并两个 PDF 文档 代码示例。
合并 PDF 流
很容易调整前面的示例以使用流而不是文件路径。以下是合并流的辅助方法:
void Merge(Stream first, Stream second, Stream result)
{
using var pdf = new PdfDocument(first);
pdf.Append(second);
pdf.Save(result);
}
合并多个 PDF 文件
您可以重复调用 Append 方法来附加多个 PDF 文件:
string[] filesToMerge = ..;
using var pdf = new PdfDocument();
foreach (string file in filesToMerge)
pdf.Append(file);
// 删除 PdfDocument() 调用添加的空白页
pdf.RemovePage(0);
pdf.Save(pathToFile);
合并加密 PDF 文件
有用于合并加密文档的 Append 重载:
using var pdf = new PdfDocument();
pdf.Append("encrypted.pdf", new PdfStandardDecryptionHandler("password"));
pdf.Save("merged.pdf");
您可以在 使用 C# 和 VB.NET 解密 PDF 文档 文章中找到更多信息。
合并 PDF 表单
PDF 文档中的每个表单字段都必须具有唯一的名称。当要合并的文档包含具有相同名称的字段时,这可能会导致问题。Docotic.Pdf 为冲突的表单控件提供了以下合并策略:
- 当附加控件与现有控件发生冲突时重命名它们
- 将附加控件合并到现有控件
- 展平附加控件
- 不附加任何控件
- 按原样附加控件
默认情况下,库会在发生冲突时重命名附加的控件。您可以使用 PdfMergingOptions 类选择替代策略:
using var pdf = new PdfDocument("form.pdf");
var decryptionHandler = new PdfStandardDecryptionHandler(string.Empty);
var mergingOptions = new PdfMergingOptions()
{
ControlMergingMode = PdfControlMergingMode.CopyAsKids
};
pdf.Append("form.pdf", decryptionHandler, mergingOptions);
pdf.Save("merged.pdf");
使用 CopyAsKids 模式,库会合并并同步冲突的控件。 即,当您更改一个控件时,第二个控件将具有相同的值。
减少合并的 PDF 文件
PDF 文档可能包含相同的对象,如字体或图像。合并此类文档时,生成的文档将包含相同对象的副本。使用 PdfDocument.ReplaceDuplicateObjects() 方法优化合并结果:
using var pdf = new PdfDocument("2024-05-28.pdf");
pdf.Append("2024-05-29.pdf");
pdf.ReplaceDuplicateObjects();
pdf.Save("merged.pdf");
您可以进一步减小输出文件的大小。例如,您可以删除未使用的字体字形或压缩图像。在 使用 C# 和 VB.NET 压缩 PDF 文档 文章中阅读有关支持的压缩选项的信息。
自定义 PDF 合并
Docotic.Pdf 提供了提取、重新排序或删除 PDF 页面的方法。您可以将它们与 Append 方法一起使用来实现自定义 PDF 合并任务。
附加特定 PDF 页面
Docotic.Pdf 还允许您合并 PDF 文档的一部分。有多种方法可以做到这一点。例如,您可以 拆分添加的 PDF 文档并附加提取的页面。以下 C# 帮助程序将选定的页面附加到 PdfDocument:
private static void AppendPart(PdfDocument pdf, string filePath, params int[] pagesToAppend)
{
using var streamToAppend = new MemoryStream();
using var other = new PdfDocument(filePath);
using var extracted = other.CopyPages(pagesToAppend);
var options = new PdfSaveOptions
{
UseObjectStreams = false
};
extracted.Save(streamToAppend, options);
pdf.Append(streamToAppend);
}
或者,您可以附加整个 PDF 文档并删除不必要的页面。以下代码示例附加了 second.pdf
的前两页:
using var pdf = new PdfDocument(@"first.pdf");
int pageCountBefore = pdf.PageCount;
pdf.Append(@"second.pdf");
pdf.RemovePages(pageCountBefore + 2);
pdf.Save(pathToFile);
另一个解决方案与 PDF 拼版有关。您可以在 相应部分 中阅读相关内容。
附加 PDF
Append 方法始终将页面附加到当前文档的末尾。如何以不同
的顺序合并 PDF 文件?有时您可以更改 Append
调用的顺序。即使用
pdf.Append("first.pdf");
pdf.Append("second.pdf");
而不是
pdf.Append("second.pdf");
pdf.Append("first.pdf");
或者,您可以在合并后重新排序页面。此 C# 代码将附加的 PDF 文档移至开头:
using var pdf = new PdfDocument(@"second.pdf");
int pageCountBefore = pdf.PageCount;
pdf.Append(@"first.pdf");
pdf.MovePages(pageCountBefore, pdf.PageCount - pageCountBefore, 0);
pdf.Save(pathToFile);
有关重新排序 PDF 页面的更多信息,请阅读:
合并 PDF
Docotic.Pdf 允许您将多个 PDF 页面合并到单个页面上。使用 PdfDocument.CreateXObject(PdfPage)方 法基于现有页面创建 PdfXObject 对象。然后,以所需的缩放比例绘 制此对象。示例代码:
using var src = new PdfDocument(@"src.pdf");
using var dest = new PdfDocument();
PdfXObject firstXObject = dest.CreateXObject(src.Pages[0]);
PdfXObject secondXObject = dest.CreateXObject(src.Pages[1]);
PdfPage page = dest.Pages[0];
page.Orientation = PdfPaperOrientation.Landscape;
double halfOfPage = page.Width / 2;
page.Canvas.DrawXObject(firstXObject, 0, 0, halfOfPage, page.Height, 0);
page.Canvas.DrawXObject(secondXObject, halfOfPage, 0, halfOfPage, page.Height, 0);
dest.Save("result.pdf");
测试来自 GitHub 的相关 从页面创建 XObject 示例项目。
合并为附件
有时,您可能需要将 PDF 文件作为附件嵌入到另一个 PDF 文件中。这也是可能的。您还可以在 PDF 页面上添加嵌入文件的链接:
using var pdf = new PdfDocument();
PdfFileSpecification first = pdf.CreateFileAttachment("first.pdf");
pdf.SharedAttachments.Add(first);
var bounds = new PdfRectangle(20, 70, 100, 100);
PdfFileSpecification fs = pdf.CreateFileAttachment("second.pdf");
pdf.Pages[0].AddFileAnnotation(bounds, fs);
pdf.Save("attachments.pdf");
您可以在 GitHub 上的 PDF 附件 组中找到相关代码示例。
在并行线程中合并
合并多个 PDF 文件时,可以并行化代码。PdfDocument 类不是线程
安全的。因此,我们需要在不同的线程中使用单独的 PdfDocument
对象。查看
在并行线程中合并 PDF 文档 代码示例以了解更多详细信息。
此代码显示了如何并行合并 PDF 流:
Stream[] documentsToMerge = ..;
int rangeSize = 50;
while (documentsToMerge.Length > rangeSize)
{
int partitionCount = (int)Math.Ceiling(documentsToMerge.Length / (double)rangeSize);
var result = new Stream[partitionCount];
var partitioner = Partitioner.Create(0, documentsToMerge.Length, rangeSize);
Parallel.ForEach(partitioner, range =>
{
int startIndex = range.Item1;
int count = range.Item2 - range.Item1;
result[startIndex / rangeSize] = MergeToStream(documentsToMerge, startIndex, count);
});
documentsToMerge = result;
}
using PdfDocument final = GetMergedDocument(documentsToMerge, 0, documentsToMerge.Length);
final.Save("merged.pdf");
private static Stream MergeToStream(Stream[] streams, int startIndex, int count)
{
using PdfDocument pdf = GetMergedDocument(streams, startIndex, count);
var result = new MemoryStream();
var options = new PdfSaveOptions
{
UseObjectStreams = false // 加快中间文档的写入速度
};
pdf.Save(result, options);
return result;
}
private static PdfDocument GetMergedDocument(Stream[] streams, int startIndex, int count)
{
var pdf = new PdfDocument();
try
{
for (int i = 0; i < count; ++i)
{
var s = streams[startIndex + i];
pdf.Append(s);
s.Dispose();
}
pdf.RemovePage(0);
pdf.ReplaceDuplicateObjects();
return pdf;
}
catch
{
pdf.Dispose();
throw;
}
}
上述代码将输入文档拆分为 rangeSize
大小的组。然后,代码将每个组并行合并为中间文档。该过程持续进行,直到输入文档的数量足够小,可以进行简单合并。
并行解决方案不一定比单线程版本更快。结果可能因输入文档的数量及其大小而异。在示例代码中,rangeSize
参数的最佳值可能更大或更小。您应该对您的应用程序进行基准测试以找到最有效的实现。
结论
您可以使用 Docotic.Pdf 库 在 C# 和 VB.NET 中合并 PDF 文档。它允许您合并文件、流或字节数组。您可以合并加密文件、PDF 表单、特定 PDF 页面。Docotic.Pdf 还可以帮助您压缩生成的文件并节省磁盘空间。
尝试使用 GitHub 上 Docotic.Pdf 示例存储库 中的代码示例。您可以在 Docotic.Pdf 下载页面 获取评估许可证密钥并下载库。