Java iText 7 Html到Pdf转换并将外部文件链接到生成的Pdf

Java iText 7 Html到Pdf转换并将外部文件链接到生成的Pdf,java,pdf,itext,html-to-pdf,Java,Pdf,Itext,Html To Pdf,我在合并由IText生成的两个PDF时遇到了一个问题。 我是iText7的新手 我正在从html创建一个pdf,并使用excel(.xls)创建另一个pdf,作为pdf的嵌入文档。 我想合并这两个文件 基本上,我想从html生成一个PDF,然后在其中附加一个excel文档,然后从这两个PDF输出组合的html outPutStream 下面是我正在使用的代码 ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStrea

我在合并由IText生成的两个PDF时遇到了一个问题。 我是iText7的新手 我正在从html创建一个pdf,并使用excel(.xls)创建另一个pdf,作为pdf的嵌入文档。 我想合并这两个文件

基本上,我想从html生成一个PDF,然后在其中附加一个excel文档,然后从这两个PDF输出组合的html outPutStream

下面是我正在使用的代码

    ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
    PdfWriter writer = new PdfWriter(htmlToPdfContent);
    PdfDocument pdf = new PdfDocument(writer);
    pdf.setTagged();
    PageSize pageSize = PageSize.A4.rotate();
    pdf.setDefaultPageSize(pageSize);
    ConverterProperties properties = new ConverterProperties();
    HtmlConverter.convertToPdf(htmlContent, pdf, properties);

    FileUtils.cleanDirectory(new File(outputDir));

    ByteArrayOutputStream pdfResult = new ByteArrayOutputStream();
    PdfWriter writerResult = new PdfWriter(pdfResult);
    PdfDocument pdfDocResult = new PdfDocument(writerResult);

    PdfReader reader = new PdfReader(new ByteArrayInputStream(htmlToPdfContent.toByteArray()));
    PdfDocument pdfDoc = new PdfDocument(reader);
    pdfDoc.copyPagesTo(1, pdfDoc.getNumberOfPages(), pdfDocResult);

    ByteArrayOutputStream pdfAttach = new ByteArrayOutputStream();
    PdfDocument pdfLaunch = new PdfDocument(new PdfWriter(pdfAttach));
    Rectangle rect = new Rectangle(36, 700, 100, 100);
    byte[] embeddedFileContentBytes = Files.readAllBytes(Paths.get(excelPath));
    PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec(pdfLaunch, embeddedFileContentBytes, null, "test.xlsx", null, null);
    PdfAnnotation attachment = new PdfFileAttachmentAnnotation(rect, fs)
            .setContents("Click me");
    pdfLaunch.addNewPage().addAnnotation(attachment);

    PdfDocument appliedChanges = new PdfDocument(new PdfReader(new ByteArrayInputStream(pdfAttach.toByteArray())));

    appliedChanges.copyPagesTo(1, appliedChanges.getNumberOfPages(), pdfDocResult);
    try(OutputStream outputStream = new FileOutputStream(dest)) {
        pdfResult.writeTo(outputStream);
    }
这是抛出异常

13:56:05.724 [main] ERROR com.itextpdf.kernel.pdf.PdfReader - Error occurred while reading cross reference table. Cross reference table will be rebuilt.
com.itextpdf.io.IOException: Error at file pointer 19,272.
    at com.itextpdf.io.source.PdfTokenizer.throwError(PdfTokenizer.java:678)
    at com.itextpdf.kernel.pdf.PdfReader.readXrefSection(PdfReader.java:801)
    at com.itextpdf.kernel.pdf.PdfReader.readXref(PdfReader.java:774)
    at com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:538)
    at com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
    at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:238)
    at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:221)
    at com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:76)
Caused by: com.itextpdf.io.IOException: xref subsection not found.
    ... 8 common frames omitted
Exception in thread "main" com.itextpdf.kernel.PdfException: Trailer not found.
    at com.itextpdf.kernel.pdf.PdfReader.rebuildXref(PdfReader.java:1064)
    at com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:543)
    at com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
    at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:238)
    at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:221)
    at com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:88)
13:56:05.773 [main] ERROR com.itextpdf.kernel.pdf.PdfReader - Error occurred while reading cross reference table. Cross reference table will be rebuilt.
com.itextpdf.io.IOException: PDF startxref not found.
    at com.itextpdf.io.source.PdfTokenizer.getStartxref(PdfTokenizer.java:262)
    at com.itextpdf.kernel.pdf.PdfReader.readXref(PdfReader.java:753)
    at com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:538)
    at com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
    at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:238)
    at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:221)
    at com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:88)
13:56:05.724[main]ERROR com.itextpdf.kernel.pdf.PdfReader-读取交叉引用表时出错。将重建交叉引用表。
com.itextpdf.io.IOException:文件指针19272处出错。
位于com.itextpdf.io.source.PdfTokenizer.throwerr(PdfTokenizer.java:678)
位于com.itextpdf.kernel.pdf.PdfReader.readXrefSection(PdfReader.java:801)
位于com.itextpdf.kernel.pdf.PdfReader.readXref(PdfReader.java:774)
位于com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:538)
位于com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
请访问com.itextpdf.kernel.pdf.PdfDocument。(PdfDocument.java:238)
请访问com.itextpdf.kernel.pdf.PdfDocument。(PdfDocument.java:221)
位于com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:76)
原因:com.itextpdf.io.IOException:未找到外部参照子节。
... 省略了8个公共框架
线程“main”com.itextpdf.kernel.PdfException中出现异常:未找到尾部。
位于com.itextpdf.kernel.pdf.PdfReader.rebuildXref(PdfReader.java:1064)
请访问com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:543)
位于com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
请访问com.itextpdf.kernel.pdf.PdfDocument。(PdfDocument.java:238)
请访问com.itextpdf.kernel.pdf.PdfDocument。(PdfDocument.java:221)
位于com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:88)
13:56:05.773[main]ERROR com.itextpdf.kernel.pdf.PdfReader-读取交叉引用表时出错。将重建交叉引用表。
com.itextpdf.io.IOException:找不到PDF startxref。
位于com.itextpdf.io.source.PdfTokenizer.getStartxref(PdfTokenizer.java:262)
位于com.itextpdf.kernel.pdf.PdfReader.readXref(PdfReader.java:753)
位于com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:538)
位于com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1818)
请访问com.itextpdf.kernel.pdf.PdfDocument。(PdfDocument.java:238)
请访问com.itextpdf.kernel.pdf.PdfDocument。(PdfDocument.java:221)
位于com.mediaocean.prisma.order.command.infrastructure.pdf.itext.PdfAttachmentLaunch.main(PdfAttachmentLaunch.java:88)
请告知。提前谢谢

关于 您对代码的更改与我在对您问题的第一次修订的回答中提出的不同,您现在将转换为以前未使用的
PdfDocument pdf
,而不是直接转换为
ByteArrayOutputStream htmltopdfccontent

这实际上也是该答案中确定的问题的可能解决方案。因此,这里不再出现例外情况:

PdfReader reader = new PdfReader(new ByteArrayInputStream(htmlToPdfContent.toByteArray()));
PdfDocument pdfDoc = new PdfDocument(reader);
相反,您现在可以在流程的更深处获得一个异常,如下所示:

PdfDocument appliedChanges = new PdfDocument(new PdfReader(new ByteArrayInputStream(pdfAttach.toByteArray())));
原因很简单,您还没有关闭
PdfDocument pdfLaunch
,它通过tearrayoutputstream pdfAttach写入
。但只有关闭才能完成输出流中的PDF。因此,添加
close()

关于 您使用
ByteArrayOutputStream htmlToPdfContent
作为两个不同PDF生成器的目标,即通过
PDFWWriter编写器
HtmlConverter.convertToPdf
调用的
PdfDocument PDF

ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(htmlToPdfContent);
PdfDocument pdf = new PdfDocument(writer);
pdf.setTagged();
PageSize pageSize = PageSize.A4.rotate();
pdf.setDefaultPageSize(pageSize);
ConverterProperties properties = new ConverterProperties();
HtmlConverter.convertToPdf(content, htmlToPdfContent, properties);
这使得
htmlToPdfContent
的内容成为它们两个输出的大杂烩,尤其不是有效的PDF

由于您没有向
pdf
添加任何内容,因此可以安全地将其删除,并将上述摘录减少到

ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
ConverterProperties properties = new ConverterProperties();
HtmlConverter.convertToPdf(content, htmlToPdfContent, properties);
关于 您对代码的更改与我在对您问题的第一次修订的回答中提出的不同,您现在将转换为以前未使用的
PdfDocument pdf
,而不是直接转换为
ByteArrayOutputStream htmltopdfccontent

这实际上也是该答案中确定的问题的可能解决方案。因此,这里不再出现例外情况:

PdfReader reader = new PdfReader(new ByteArrayInputStream(htmlToPdfContent.toByteArray()));
PdfDocument pdfDoc = new PdfDocument(reader);
相反,您现在可以在流程的更深处获得一个异常,如下所示:

PdfDocument appliedChanges = new PdfDocument(new PdfReader(new ByteArrayInputStream(pdfAttach.toByteArray())));
原因很简单,您还没有关闭
PdfDocument pdfLaunch
,它通过tearrayoutputstream pdfAttach写入
。但只有关闭才能完成输出流中的PDF。因此,添加
close()

关于 您使用
ByteArrayOutputStream htmlToPdfContent
作为两个不同PDF生成器的目标,即通过
PDFWWriter编写器
HtmlConverter.convertToPdf
调用的
PdfDocument PDF

ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(htmlToPdfContent);
PdfDocument pdf = new PdfDocument(writer);
pdf.setTagged();
PageSize pageSize = PageSize.A4.rotate();
pdf.setDefaultPageSize(pageSize);
ConverterProperties properties = new ConverterProperties();
HtmlConverter.convertToPdf(content, htmlToPdfContent, properties);
这使得
htmlToPdfContent
的内容成为它们两个输出的大杂烩,尤其不是有效的PDF

由于您没有向
pdf
添加任何内容,因此可以安全地将其删除,并将上述摘录减少到

ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
ConverterProperties properties = new ConverterProperties();
HtmlConverter.convertToPdf(content, htmlToPdfContent, properties);

我之所以使用这段代码,是因为我想在横向模式下使用pdf。因此,为了旋转,我将pdf实例传递给writer,我在第
PdfDocument appliedChanges=new PdfDocument(new PdfReader(new ByteArrayInputStream(pdfAttach.toByteArray())行中进行了建议的更改并获得了错误获取此错误:未找到PDF startxref/com.itextpdf.kernel.PdfException:未找到拖车。是否可以将excel作为附件添加到HTMLOPDFConverter中?“是否也可以将excel作为附件添加到HTMLOPDFConverter中?”-我不知道。我对此表示怀疑,但我自己不使用html到pdf的转换,所以我不喜欢
HtmlToPdfConverter
details…@NeerajKunturkar顺便问一下,你的cod有什么原因吗