为什么飞碟总是在A4纸上打印PDF?

Why is flying saucer always printing PDF on A4 paper?

我正在尝试使用飞碟将 html 文档保存为 PDF,但是当我查看 Adob​​e Reader 的文档属性时,生成的文档最终总是具有 A4 尺寸(页面大小: 8.26 x 11.69 英寸).

我确实阅读了文档并且我传递了 css @page {size: letter;} 样式。虽然它确实对输出有影响,但页面大小在 Adob​​e Reader 中始终保持 8.26 x 11.69。例如,如果我将页面大小设置为 legal,我的 PDF 仍然是 A4 的大小,但文档的顶部不见了,就好像它从 "paper".

上掉下来了一样

我不确定问题是出在itext这边还是飞碟这边。我使用的是相当旧的版本,所以我的第一步是升级到最新的飞碟 9.1.6 版本。我也从 itext 2.0.8 移动到 openPDF 1.0.1 但我仍然得到相同的行为。

我还在调试器中跟踪到 com.lowagie.text.Document 在 ITextRenderer 中创建,此时传递的文档大小是正确的。这让我觉得问题可能出在 openPDF / iText 中,但我找不到我做错了什么。

真正的问题是您(无意中)使用了不再受支持的软件。任何仍然具有命名空间 lowagie(iText 的创始人和 CTO)的东西都已经过时了。

如果您只想将 HTML 转换为 pdf,为什么不直接使用 iText 并省去中间人?

我们为您提供多种选择。

  1. XMLWorker(基于 iText5 的代码,将 HTML 转换为 pdf)
  2. pdfHTML(基于 iText7 的附加组件,可将 HTML5/CSS3 转换为 pdf)

这是一个相当广泛的使用 pdf 的代码示例HTML:

public void createPdf(String src, String dest, String resources) throws IOException {
    try {
        FileOutputStream outputStream = new FileOutputStream(dest);

        WriterProperties writerProperties = new WriterProperties();
        //Add metadata
        writerProperties.addXmpMetadata();

        PdfWriter pdfWriter = new PdfWriter(outputStream, writerProperties);

        PdfDocument pdfDoc = new PdfDocument(pdfWriter);
        pdfDoc.getCatalog().setLang(new PdfString("en-US"));
        //Set the document to be tagged
        pdfDoc.setTagged();
        pdfDoc.getCatalog().setViewerPreferences(new PdfViewerPreferences().setDisplayDocTitle(true));

        //Set meta tags
        PdfDocumentInfo pdfMetaData = pdfDoc.getDocumentInfo();
        pdfMetaData.setAuthor("Joris Schellekens");
        pdfMetaData.addCreationDate();
        pdfMetaData.getProducer();
        pdfMetaData.setCreator("iText Software");
        pdfMetaData.setKeywords("example, accessibility");
        pdfMetaData.setSubject("PDF accessibility");
        //Title is derived from html

        // pdf conversion
        ConverterProperties props = new ConverterProperties();
        FontProvider fp = new FontProvider();
        fp.addStandardPdfFonts();
        fp.addDirectory(resources);//The noto-nashk font file (.ttf extension) is placed in the resources

        props.setFontProvider(fp);
        props.setBaseUri(resources);
        //Setup custom tagworker factory for better tagging of headers
        DefaultTagWorkerFactory tagWorkerFactory = new AccessibilityTagWorkerFactory();
        props.setTagWorkerFactory(tagWorkerFactory);

        HtmlConverter.convertToPdf(new FileInputStream(src), pdfDoc, props);
        pdfDoc.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

您可以在 http://itextpdf.com/itext7/pdfHTML

找到更多信息

事实证明,PDF 生成正确地使用了@page 大小声明,并且问题后来出现在我们的软件中。我没有注意到的是,在生成 PDF 之后,调用了另一种方法将多个 PDF 合并为一个。可能不应该调用此方法,但那是另一回事了。

最重要的是这个方法创建了一个 new com.lowagie.text.Document(),它默认创建一个 A4 大小的文档,然后遍历 pdf 的所有页面,使用 [=12 添加页面到新文档=].这些导入的页面没有保留其原始大小。

我在创建合并文档对象时通过传递第一页的页面大小来修复它:

document = new Document(pdfReader.getPageSize(1));