我在网上搜索了有关如何执行此操作的示例。我发现了一些似乎比他们需要的更多的参与。所以我的问题是,使用 iTextSharp,是否有一种相当简洁的方法可以将一个 PDF 文档附加到另一个文档?
最好这不会涉及第三个文件。只需打开第一个 PDF 文档,将第二个 PDF 文档附加到第一个 PDF 文档,然后将它们都关闭。
我在网上搜索了有关如何执行此操作的示例。我发现了一些似乎比他们需要的更多的参与。所以我的问题是,使用 iTextSharp,是否有一种相当简洁的方法可以将一个 PDF 文档附加到另一个文档?
最好这不会涉及第三个文件。只需打开第一个 PDF 文档,将第二个 PDF 文档附加到第一个 PDF 文档,然后将它们都关闭。
我真的可能遗漏了一些东西,但我做了一些更简单的事情。我承认这个解决方案可能不会更新书签(就像迄今为止最好的答案一样),但它对我来说完美无缺。由于我将文档与可填写的表单合并,因此我使用了 PdfCopyFields 而不是 PdfCopy。
这是代码(我已经剥离了所有错误处理以使实际代码更加可见,如果您打算使用代码,请添加 try..finally 以关闭打开的资源):
void MergePdfStreams(List<Stream> Source, Stream Dest)
{
PdfCopyFields copy = new PdfCopyFields(Dest);
foreach (Stream source in Source)
{
PdfReader reader = new PdfReader(source);
copy.AddDocument(reader);
}
copy.Close();
}
您可以传递任何流,无论是 FileStream、MemoryStream(在从数据库读取 PDF 时很有用,不需要临时文件等)
示例用法:
void TestMergePdfStreams()
{
List<Stream> sources = new List<Stream>()
{
new FileStream("template1.pdf", FileMode.Open),
new FileStream("template2.pdf", FileMode.Open),
new MemoryStream((byte[])someDataRow["PDF_COLUMN_NAME"])
};
MergePdfStreams(sources, new FileStream("MergedOutput.pdf", FileMode.Create));
}
好的,这不是直截了当的,但它可以工作并且速度惊人。(并且它使用第三个文件,没有打开和附加之类的东西。)我在文档/示例中“发现”了这一点。这是代码:
private void CombineMultiplePDFs( string[] fileNames, string outFile ) {
int pageOffset = 0;
ArrayList master = new ArrayList();
int f = 0;
Document document = null;
PdfCopy writer = null;
while ( f < fileNames.Length ) {
// we create a reader for a certain document
PdfReader reader = new PdfReader( fileNames[ f ] );
reader.ConsolidateNamedDestinations();
// we retrieve the total number of pages
int n = reader.NumberOfPages;
ArrayList bookmarks = SimpleBookmark.GetBookmark( reader );
if ( bookmarks != null ) {
if ( pageOffset != 0 ) {
SimpleBookmark.ShiftPageNumbers( bookmarks, pageOffset, null );
}
master.AddRange( bookmarks );
}
pageOffset += n;
if ( f == 0 ) {
// step 1: creation of a document-object
document = new Document( reader.GetPageSizeWithRotation( 1 ) );
// step 2: we create a writer that listens to the document
writer = new PdfCopy( document, new FileStream( outFile, FileMode.Create ) );
// step 3: we open the document
document.Open();
}
// step 4: we add content
for ( int i = 0; i < n; ) {
++i;
if ( writer != null ) {
PdfImportedPage page = writer.GetImportedPage( reader, i );
writer.AddPage( page );
}
}
PRAcroForm form = reader.AcroForm;
if ( form != null && writer != null ) {
writer.CopyAcroForm( reader );
}
f++;
}
if ( master.Count > 0 && writer != null ) {
writer.Outlines = master;
}
// step 5: we close the document
if ( document != null ) {
document.Close();
}
}
是的。我在 iText 论坛上看到过一个名为 PdfManipulation 的课程。不过,使用该类将涉及第三个文件。
该类最初在 VB.Net 中。我从vbforums.com 上的帖子下载了它。显然,它没有合并文件功能,所以我根据该类中的代码编写了一个。
这是在没有 iTextSharp 的机器上编写的。这可能有错误。我什至不确定页码是基于 0 还是基于 1。但是试一试。
public static void MergePdfFiles(IEnumerable<string> files, string output) {
iTextSharp.text.Document doc;
iTextSharp.text.pdf.PdfCopy pdfCpy;
doc = new iTextSharp.text.Document();
pdfCpy = new iTextSharp.text.pdf.PdfCopy(doc, new System.IO.FileStream(output, System.IO.FileMode.Create));
doc.Open();
foreach (string file in files) {
// initialize a reader
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(file);
int pageCount = reader.NumberOfPages;
// set page size for the documents
doc.SetPageSize(reader.GetPageSizeWithRotation(1));
for (int pageNum = 1; pageNum <= pageCount; pageNum++) {
iTextSharp.text.pdf.PdfImportedPage page = pdfCpy.GetImportedPage(reader, pageNum);
pdfCpy.AddPage(page);
}
reader.Close();
}
doc.Close();
}
我不知道如何对 PDF 文件执行此操作,但对于 postscript,您只需连接文件即可。如果您安装了 pdf2ps 和 ps2pdf,下面将完成这项工作:
pdf2ps file1.pdf file1.ps
pdf2ps file2.pdf file2.ps
cat file1.ps file2.ps > combined.ps
ps2pdf combined.ps combined.pdf
我不是 pdf2ps 或 ps2pdf 方面的专家。我只使用过 ps2pdf,当我这样做时,它会将文本保留为文本(我仍然可以从生成的 pdf 中选择和复制文本)。当我执行上述步骤(pdf->ps、combine、ps->pdf)时,我最终会得到一个像图像一样的 pdf。不知道为什么。