如何使用 C# iText7 将 PDF 包中的所有 pdf 文件合并为普通 pdf 文件?
How to merge all pdf files from a PDF Portfolio to a normal pdf file using C# iText7?
我 this C# example 并尝试将附件作为 PdfDocument 获取,但我不知道该怎么做。
最后,我想简单地将投资组合中包含的每个 pdf 文件合并到一个“普通”pdf 文件中。应忽略每个非 pdf 附件。
编辑:
(好吧,抱歉说得太含糊了。说出我想要达到的目的,只是想让你们更容易帮助我。我不想让你们帮我写程序。)
因此,这是链接示例中的部分代码:
protected void ManipulatePdf(String dest)
{
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
PdfDictionary root = pdfDoc.GetCatalog().GetPdfObject();
PdfDictionary names = root.GetAsDictionary(PdfName.Names);
PdfDictionary embeddedFiles = names.GetAsDictionary(PdfName.EmbeddedFiles);
PdfArray namesArray = embeddedFiles.GetAsArray(PdfName.Names);
// Remove the description of the embedded file
namesArray.Remove(0);
// Remove the reference to the embedded file.
namesArray.Remove(0);
pdfDoc.Close();
}
我不想从源文档中删除任何内容,而是想知道如何在可能的情况下从 PdfArray 中获取 PdfDocument 对象。
示例文件:
http://www.mediafire.com/file/c4tw07wci8swdx9/NPort_5000.pdf/file
移植到C#的mkl解决方案:
PdfNameTree embeddedFilesTree = pdfDocument.GetCatalog().GetNameTree(PdfName.EmbeddedFiles);
IDictionary<string, PdfObject> embeddedFilesMap = embeddedFilesTree.GetNames();
List<PdfStream> embeddedPdfs = new List<PdfStream>();
foreach (PdfObject pdfObject in embeddedFilesMap.Values)
{
if (!(pdfObject is PdfDictionary))
continue;
PdfDictionary filespecDict = (PdfDictionary)pdfObject;
PdfDictionary embeddedFileDict = filespecDict.GetAsDictionary(PdfName.EF);
if (embeddedFileDict == null)
continue;
PdfStream embeddedFileStream = embeddedFileDict.GetAsStream(PdfName.F);
if (embeddedFileStream == null)
continue;
PdfName subtype = embeddedFileStream.GetAsName(PdfName.Subtype);
if (PdfName.ApplicationPdf.CompareTo(subtype) != 0)
continue;
embeddedPdfs.Add(embeddedFileStream);
}
if (embeddedPdfs.Count > 0)
{
PdfWriter pdfWriter = new PdfWriter("NPort_5000-flat.pdf", new WriterProperties().SetFullCompressionMode(true));
PdfDocument flatPdfDocument = new PdfDocument(pdfWriter);
PdfMerger pdfMerger = new PdfMerger(flatPdfDocument);
RandomAccessSourceFactory sourceFactory = new RandomAccessSourceFactory();
foreach (PdfStream pdfStream in embeddedPdfs)
{
PdfReader embeddedReader = new PdfReader(sourceFactory.CreateSource(pdfStream.GetBytes()), new ReaderProperties());
PdfDocument embeddedPdfDocument = new PdfDocument(embeddedReader);
pdfMerger.Merge(embeddedPdfDocument, 1, embeddedPdfDocument.GetNumberOfPages());
}
flatPdfDocument.Close();
}
要将 PDF 包中的所有 pdf 文件合并到普通 pdf 文件,您必须遍历 EmbeddedFiles 的名称树,检索其中所有PDF的流,然后合并所有这些PDF。
对于在 PdfDocument pdfDocument
中加载的投资组合(Java 版本;OP 在他的问题正文中编辑了一个 C# 端口):
PdfNameTree embeddedFilesTree = pdfDocument.getCatalog().getNameTree(PdfName.EmbeddedFiles);
Map<String, PdfObject> embeddedFilesMap = embeddedFilesTree.getNames();
List<PdfStream> embeddedPdfs = new ArrayList<PdfStream>();
for (Map.Entry<String, PdfObject> entry : embeddedFilesMap.entrySet()) {
PdfObject pdfObject = entry.getValue();
if (!(pdfObject instanceof PdfDictionary))
continue;
PdfDictionary filespecDict = (PdfDictionary) pdfObject;
PdfDictionary embeddedFileDict = filespecDict.getAsDictionary(PdfName.EF);
if (embeddedFileDict == null)
continue;
PdfStream embeddedFileStream = embeddedFileDict.getAsStream(PdfName.F);
if (embeddedFileStream == null)
continue;
PdfName subtype = embeddedFileStream.getAsName(PdfName.Subtype);
if (!PdfName.ApplicationPdf.equals(subtype))
continue;
embeddedPdfs.add(embeddedFileStream);
}
Assert.assertFalse("No embedded PDFs found", embeddedPdfs.isEmpty());
try ( PdfWriter pdfWriter = new PdfWriter("NPort_5000-flat.pdf", new WriterProperties().setFullCompressionMode(true));
PdfDocument flatPdfDocument = new PdfDocument(pdfWriter) ) {
PdfMerger pdfMerger = new PdfMerger(flatPdfDocument);
RandomAccessSourceFactory sourceFactory = new RandomAccessSourceFactory();
for (PdfStream pdfStream : embeddedPdfs) {
try ( PdfReader embeddedReader = new PdfReader(sourceFactory.createSource(pdfStream.getBytes()), new ReaderProperties());
PdfDocument embeddedPdfDocument = new PdfDocument(embeddedReader)) {
pdfMerger.merge(embeddedPdfDocument, 1, embeddedPdfDocument.getNumberOfPages());
}
}
}
(FlattenPortfolio 测试 testFlattenNPort_5000
)
我 this C# example 并尝试将附件作为 PdfDocument 获取,但我不知道该怎么做。
最后,我想简单地将投资组合中包含的每个 pdf 文件合并到一个“普通”pdf 文件中。应忽略每个非 pdf 附件。
编辑:
(好吧,抱歉说得太含糊了。说出我想要达到的目的,只是想让你们更容易帮助我。我不想让你们帮我写程序。)
因此,这是链接示例中的部分代码:
protected void ManipulatePdf(String dest)
{
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
PdfDictionary root = pdfDoc.GetCatalog().GetPdfObject();
PdfDictionary names = root.GetAsDictionary(PdfName.Names);
PdfDictionary embeddedFiles = names.GetAsDictionary(PdfName.EmbeddedFiles);
PdfArray namesArray = embeddedFiles.GetAsArray(PdfName.Names);
// Remove the description of the embedded file
namesArray.Remove(0);
// Remove the reference to the embedded file.
namesArray.Remove(0);
pdfDoc.Close();
}
我不想从源文档中删除任何内容,而是想知道如何在可能的情况下从 PdfArray 中获取 PdfDocument 对象。
示例文件: http://www.mediafire.com/file/c4tw07wci8swdx9/NPort_5000.pdf/file
移植到C#的mkl解决方案:
PdfNameTree embeddedFilesTree = pdfDocument.GetCatalog().GetNameTree(PdfName.EmbeddedFiles);
IDictionary<string, PdfObject> embeddedFilesMap = embeddedFilesTree.GetNames();
List<PdfStream> embeddedPdfs = new List<PdfStream>();
foreach (PdfObject pdfObject in embeddedFilesMap.Values)
{
if (!(pdfObject is PdfDictionary))
continue;
PdfDictionary filespecDict = (PdfDictionary)pdfObject;
PdfDictionary embeddedFileDict = filespecDict.GetAsDictionary(PdfName.EF);
if (embeddedFileDict == null)
continue;
PdfStream embeddedFileStream = embeddedFileDict.GetAsStream(PdfName.F);
if (embeddedFileStream == null)
continue;
PdfName subtype = embeddedFileStream.GetAsName(PdfName.Subtype);
if (PdfName.ApplicationPdf.CompareTo(subtype) != 0)
continue;
embeddedPdfs.Add(embeddedFileStream);
}
if (embeddedPdfs.Count > 0)
{
PdfWriter pdfWriter = new PdfWriter("NPort_5000-flat.pdf", new WriterProperties().SetFullCompressionMode(true));
PdfDocument flatPdfDocument = new PdfDocument(pdfWriter);
PdfMerger pdfMerger = new PdfMerger(flatPdfDocument);
RandomAccessSourceFactory sourceFactory = new RandomAccessSourceFactory();
foreach (PdfStream pdfStream in embeddedPdfs)
{
PdfReader embeddedReader = new PdfReader(sourceFactory.CreateSource(pdfStream.GetBytes()), new ReaderProperties());
PdfDocument embeddedPdfDocument = new PdfDocument(embeddedReader);
pdfMerger.Merge(embeddedPdfDocument, 1, embeddedPdfDocument.GetNumberOfPages());
}
flatPdfDocument.Close();
}
要将 PDF 包中的所有 pdf 文件合并到普通 pdf 文件,您必须遍历 EmbeddedFiles 的名称树,检索其中所有PDF的流,然后合并所有这些PDF。
对于在 PdfDocument pdfDocument
中加载的投资组合(Java 版本;OP 在他的问题正文中编辑了一个 C# 端口):
PdfNameTree embeddedFilesTree = pdfDocument.getCatalog().getNameTree(PdfName.EmbeddedFiles);
Map<String, PdfObject> embeddedFilesMap = embeddedFilesTree.getNames();
List<PdfStream> embeddedPdfs = new ArrayList<PdfStream>();
for (Map.Entry<String, PdfObject> entry : embeddedFilesMap.entrySet()) {
PdfObject pdfObject = entry.getValue();
if (!(pdfObject instanceof PdfDictionary))
continue;
PdfDictionary filespecDict = (PdfDictionary) pdfObject;
PdfDictionary embeddedFileDict = filespecDict.getAsDictionary(PdfName.EF);
if (embeddedFileDict == null)
continue;
PdfStream embeddedFileStream = embeddedFileDict.getAsStream(PdfName.F);
if (embeddedFileStream == null)
continue;
PdfName subtype = embeddedFileStream.getAsName(PdfName.Subtype);
if (!PdfName.ApplicationPdf.equals(subtype))
continue;
embeddedPdfs.add(embeddedFileStream);
}
Assert.assertFalse("No embedded PDFs found", embeddedPdfs.isEmpty());
try ( PdfWriter pdfWriter = new PdfWriter("NPort_5000-flat.pdf", new WriterProperties().setFullCompressionMode(true));
PdfDocument flatPdfDocument = new PdfDocument(pdfWriter) ) {
PdfMerger pdfMerger = new PdfMerger(flatPdfDocument);
RandomAccessSourceFactory sourceFactory = new RandomAccessSourceFactory();
for (PdfStream pdfStream : embeddedPdfs) {
try ( PdfReader embeddedReader = new PdfReader(sourceFactory.createSource(pdfStream.getBytes()), new ReaderProperties());
PdfDocument embeddedPdfDocument = new PdfDocument(embeddedReader)) {
pdfMerger.merge(embeddedPdfDocument, 1, embeddedPdfDocument.getNumberOfPages());
}
}
}
(FlattenPortfolio 测试 testFlattenNPort_5000
)