使用iText pdfHTML的PDF的页面大小和格式 [英] Page size and formatting of PDF using iText pdfHTML

查看:158
本文介绍了使用iText pdfHTML的PDF的页面大小和格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 jsFiddle链接到我的HTML渲染器正在使用的HTML代码.

I am trying to export 3 HTML pages (all with same content) into a PDF using iText7.1.0 and pdfHTML2.0.0 using this example. For some reason, the pages have formatting issue at the footer. The jsFiddle link to my HTML code that is being used by PDF renderer.

以下是用于呈现PDF的Java代码(Test.html与小提琴中的HTML代码相同):

Below is the Java code used for rendering the PDF (Test.html is the same HTML code in the fiddle):

package com.itextpdf.htmlsamples.chapter01;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.utils.PdfMerger;
import com.itextpdf.licensekey.LicenseKey;

/**
 * Can we parse different HTML files and combine them into one PDF?
 * Yes, this can be done in different ways. This example shows how
 * to create a PDF in memory for each HTML, then use PdfMerger to
 * merge the different PDFs into one, on a page per page basis.
 */
public class C07E01_CombineHtml {

    /** The Base URI of the HTML page. */
    public static final String BASEURI = "src/main/resources/html/";
    /** An array containing the paths to different HTML files. */
    public static final String[] SRC = {
            String.format("%sTest.html", BASEURI),
            String.format("%sTest.html", BASEURI),
            String.format("%sTest.html", BASEURI)
    };
    /** The target folder for the result. */
    public static final String TARGET = "target/results/ch07/";
    /** The path to the resulting PDF file. */
    public static final String DEST = String.format("%sbundle.pdf", TARGET);
    protected PageSize A4;

    /**
     * The main method of this example.
     *
     * @param args no arguments are needed to run this example.
     * @throws IOException Signals that an I/O exception has occurred.
     */
    public static void main(String[] args) throws IOException {
        LicenseKey.loadLicenseFile("C://Users//Sparks//Desktop//itextkey-0.xml");
        File file = new File(TARGET);
        file.mkdirs();
        new C07E01_CombineHtml().createPdf(BASEURI, SRC, DEST);
    }

    /**
     * Creates the PDF file.
     *
     * @param baseUri the base URI
     * @param src an array with the paths to different source HTML files
     * @param dest the path to the resulting PDF
     * @throws IOException Signals that an I/O exception has occurred.
     */
    public void createPdf(String baseUri, String[] src, String dest) throws IOException { 
        ConverterProperties properties = new ConverterProperties();
        properties.setBaseUri(baseUri);
        PdfWriter writer = new PdfWriter(dest);
        PdfDocument pdf = new PdfDocument(writer);
        PdfMerger merger = new PdfMerger(pdf);
        for (String html : src) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfDocument temp = new PdfDocument(new PdfWriter(baos));
            PageSize pageSize = PageSize.A4;
            temp.setDefaultPageSize(pageSize);
            HtmlConverter.convertToPdf(new FileInputStream(html), temp, properties);
            temp = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())));
            merger.merge(temp, 1, temp.getNumberOfPages());
            temp.close();
        }
        pdf.close();
    }
}

输出PDF文件有6页,没有页脚.每页应有3页,尺寸为"A4".

The output PDF file has 6 pages without footer. It should have 3 pages each of 'A4' size.

任何建议都会有所帮助.

Any suggestions would be helpful.

推荐答案

将PageSize更改为较大的大小应该可以解决此特定问题. 之后,您可以按比例缩小页面,以获取带有A4页的PDF. 看看下面的代码示例,以了解如何执行此操作.

Changing the PageSize to one that is larger should solve this specific issue. Afterward you can scale the page down in order to get a PDF with A4 pages. Take a look at the code sample below to get an idea about how you can do this.

public static void main(String[] args) throws IOException {
    ByteArrayOutputStream pdf = createPdf("src/main/resources/SO47869248/html.html");
    // To get from A3 to A4 the size has to shrink 71%
    new SO47869248().scalePdf(DEST, new ByteArrayInputStream(pdf.toByteArray()), 0.7071f);
}

public static ByteArrayOutputStream createPdf(String htmlSrc) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    ConverterProperties converterProperties = new ConverterProperties();
    converterProperties.setBaseUri(new File(htmlSrc).getParent());
    PdfWriter writer = new PdfWriter(output);
    PdfDocument pdfDocument = new PdfDocument(writer);
    PdfMerger merger = new PdfMerger(pdfDocument);
    for(int x=0; x < 3; x++){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfDocument temp = new PdfDocument(new PdfWriter(baos));
        temp.setDefaultPageSize(PageSize.A3);
        HtmlConverter.convertToPdf(new FileInputStream(htmlSrc), temp, converterProperties);
        temp = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())));
        merger.merge(temp, 1, temp.getNumberOfPages());
        temp.close();
    }
    pdfDocument.close();

    return output;
}

public void scalePdf(String dest, ByteArrayInputStream input, float scale) throws IOException {
    // Create the source document
    PdfDocument srcDoc = new PdfDocument(new PdfReader(input));
    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
    ScaleDownEventHandler eventHandler = new ScaleDownEventHandler(scale);
    int n = srcDoc.getNumberOfPages();
    pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE, eventHandler);

    PdfCanvas canvas;
    PdfFormXObject page;
    for (int p = 1; p <= n; p++) {
        eventHandler.setPageDict(srcDoc.getPage(p).getPdfObject());
        canvas = new PdfCanvas(pdfDoc.addNewPage());
        page = srcDoc.getPage(p).copyAsFormXObject(pdfDoc);
        canvas.addXObject(page, scale, 0f, 0f, scale, 0f, 0f);
    }

    pdfDoc.close();
    srcDoc.close();
}

protected class ScaleDownEventHandler implements IEventHandler {
    protected float scale = 1;
    protected PdfDictionary pageDict;

    public ScaleDownEventHandler(float scale) {
        this.scale = scale;
    }

    public void setPageDict(PdfDictionary pageDict) {
        this.pageDict = pageDict;
    }

    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfPage page = docEvent.getPage();
        page.put(PdfName.Rotate, pageDict.getAsNumber(PdfName.Rotate));

        scaleDown(page, pageDict, PdfName.MediaBox, scale);
        scaleDown(page, pageDict, PdfName.CropBox, scale);
    }

    protected void scaleDown(PdfPage destPage, PdfDictionary pageDictSrc, PdfName box, float scale) {
        PdfArray original = pageDictSrc.getAsArray(box);
        if (original != null) {
            float width = original.getAsNumber(2).floatValue() - original.getAsNumber(0).floatValue();
            float height = original.getAsNumber(3).floatValue() - original.getAsNumber(1).floatValue();
            PdfArray result = new PdfArray();
            result.add(new PdfNumber(0));
            result.add(new PdfNumber(0));
            result.add(new PdfNumber(width * scale));
            result.add(new PdfNumber(height * scale));
            destPage.put(box, result);
        }
    }
}

在此示例中,我选择了A3页面大小常量.您还可以使用特定的度量来创建PageSize对象.如下图所示:

For this example I picked the A3 pagesize constant. You can also create a PageSize object using specific measurements. As shown below:

构造函数:

public PageSize(float width, float height)

示例:

PageSize pageSize = new PageSize(750, 1000);
PdfDocument temp = new PdfDocument(pageSize);

这篇关于使用iText pdfHTML的PDF的页面大小和格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆