C# 将PDF中的外部链接转换为iTextSharp中嵌入附件的链接
我的任务有点奇怪。我们即将关闭一个相当大的内部解决方案,并希望一次性导出它所持有的数据 该解决方案生成PDF格式的报告。这些PDF大多包含文本,但也包含图像。图像是激活后打开浏览器并指向图像完整版本的链接 由于我们将要关闭底层系统,到全尺寸图像的外部链接也将停止工作 出于各种奇怪的原因,我们对报告生成本身的控制有限,因此我们主要局限于报告的后处理 到目前为止,我设计的计划是从系统生成所有必要的报告,并通过iTextSharp进行处理。“所有”我试图实现的是处理每一份PDF,并且:C# 将PDF中的外部链接转换为iTextSharp中嵌入附件的链接,c#,itext,pdf-generation,C#,Itext,Pdf Generation,我的任务有点奇怪。我们即将关闭一个相当大的内部解决方案,并希望一次性导出它所持有的数据 该解决方案生成PDF格式的报告。这些PDF大多包含文本,但也包含图像。图像是激活后打开浏览器并指向图像完整版本的链接 由于我们将要关闭底层系统,到全尺寸图像的外部链接也将停止工作 出于各种奇怪的原因,我们对报告生成本身的控制有限,因此我们主要局限于报告的后处理 到目前为止,我设计的计划是从系统生成所有必要的报告,并通过iTextSharp进行处理。“所有”我试图实现的是处理每一份PDF,并且: 搜索外部链接
if (AnnotationDictionary.Get(PdfName.A) != null)
{
var annotActionObject = AnnotationDictionary.Get(PdfName.A);
var AnnotationAction = (PdfDictionary)(annotActionObject.IsIndirect() ? PdfReader.GetPdfObject(annotActionObject) : annotActionObject);
var type = AnnotationAction.Get(PdfName.S);
//Test if it is a URI action
if (type.Equals(PdfName.URI))
{
//Attach the downloaded file
PdfFileSpecification pfs = PdfFileSpecification.FileEmbedded(writer, embFile.Path, embFile.Description, null);
pfs.AddDescription(embFile.Description, false);
writer.AddFileAttachment(pfs);
//Removing old annotation
AnnotationAction.Remove(PdfName.A);
AnnotationDictionary.Remove(PdfName.A);
PdfDestination destination = new PdfDestination(PdfDestination.FIT);
destination.AddFirst(new PdfNumber(1));
var target = new PdfTargetDictionary(true);
target.EmbeddedFileName = embFile.Name;
PdfAction action = PdfAction.GotoEmbedded(null, target, destination, true);
AnnotationDictionary.Put(PdfName.D, action.Get(PdfName.D));
AnnotationAction.Put(PdfName.D, action.Get(PdfName.D));
}
}
对某些人来说,这很可能相当明显,为什么它不起作用:)
现在,一切正常,它在另一端吐出一个PDF。如前所述,PDF中的图像不再具有活动链接,所有附加文件都按预期嵌入。然而,到嵌入式资源的链接不起作用,而且任何地方都没有它的迹象
非常感谢所有反馈。谢谢。如评论中所述,您只能链接到嵌入的PDF文件 您只需更改
D
项。您需要覆盖整个A
条目,但请确保保留目标的位置
下面是我创建的一个快速POC:
PdfReader reader = new PdfReader(INPUT_FILE);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(OUTPUT_FILE));
PdfFileSpecification fs = PdfFileSpecification.fileEmbedded(stamper.getWriter(), null, "EmbeddedFile.pdf", FileUtils.readFileToByteArray(new File(INPUT_FOLDER + "embeddedfile.pdf")));
fs.addDescription("specificname", false);
stamper.getWriter().addFileAttachment(fs);
PdfTargetDictionary targetDictionary = new PdfTargetDictionary(true);
targetDictionary.setEmbeddedFileName("specificname");
PdfDestination dest = new PdfDestination(PdfDestination.FIT);
dest.addFirst(new PdfNumber(1));
PdfAction action = PdfAction.gotoEmbedded(null, targetDictionary, dest, true);
PdfDictionary page = reader.getPageN(1);
PdfArray annotations = page.getAsArray(PdfName.ANNOTS);
for(int x=0;x<annotations.size();x++) {
PdfDictionary annotation = annotations.getAsDict(x);
PdfArray location = annotation.getAsArray(PdfName.RECT);
action.put(PdfName.RECT,location);
annotation.put(PdfName.A, action);
}
stamper.close();
PdfReader reader=新的PdfReader(输入_文件);
PdfStamper stamper=新PdfStamper(读取器,新文件输出流(输出文件));
PdfFileSpecification fs=PdfFileSpecification.fileEmbedded(stamper.getWriter(),null,“EmbeddedFile.pdf”,FileUtils.readFileToByteArray(新文件(输入文件夹+“EmbeddedFile.pdf”));
fs.addDescription(“具体名称”,假);
stamper.getWriter().addFileAttachment(fs);
PdfTargetDictionary targetDictionary=新的PdfTargetDictionary(true);
setEmbeddedFileName(“specificname”);
PDFDestimation dest=新的PDFDestimation(PDFDestimation.FIT);
目的地地址第一(新的PDFN编号(1));
PdAction=PdAction.gotoEmbedded(null,targetDictionary,dest,true);
PdfDictionary page=reader.getPageN(1);
PdfArray annotations=page.getAsArray(PdfName.ANNOTS);
对于(int x=0;x),很遗憾,这是一个无法满足的要求。请参阅和PDF规范的相关章节。通过goToEmbedded()
方法创建的GoTo操作只能有效地打开嵌入的PDF文件。最新版本的PDF规范ISO 32000-2甚至使其更为明确:“注意:嵌入到操作仅适用于PDF类型的文件"。其他文件格式,很可能是出于安全考虑,无法通过该操作打开。@JonReilly,谢谢你。我最近在其他地方遇到了这些详细信息。我只是尝试添加PDF而不是图像。不幸的是,我的操作仍然不起作用。Acrobat Reader中没有抛出错误或警告,因此我没有真正执行此操作有什么可以遵循的吗?你精通iTextSharp来评论我的代码吗?理论上,因为我为iText=P工作。我将添加一个快速的答案。非常感谢!经过一些调整,我成功地让它在我的应用程序中工作。现在,这只是一个关于下一步的内部讨论。再次,非常感谢你为我们精心设计的答案和样本。