PdfBox将多个图像添加到pdf中

时间:2017-12-22 00:13:16

标签: java pdfbox

我尝试使用pdfbox 2.0.8将多个图像添加到pdf中,但目前只添加一个。我有两个不同的图像应该附加到两个不同的acrofields,但只会添加我的列表中的最后一个。

这是我的测试功能:

@Test
public void attachBulkImageToField(){

    List<ImageData> data = new ArrayList<>();

    data.add(new ImageData(signatureAusstellerField,signatureAussteller.toPath()));
    data.add(new ImageData(signatureDienstleisterField, signatureDienstleister.toPath()));

    ImageToFieldDrawer imgDrawer = new ImageToFieldDrawer(pdf);
    assertTrue(imgDrawer.drawImageToField(data, Paths.get("d:\\imageBulk.pdf")));

}


public boolean drawImageToField(List<ImageData> data, final Path outPath) {
    try {
        for (ImageData element : data) {
            addImageForField(element.getImagePath(), getAcroFieldWithName(element.getFieldName()));
        }
        savePdf(outPath);
        return true;

    } catch (IOException e) {
        e.printStackTrace();
    } catch (PDFSizeException e) {
        e.printStackTrace();
    }
    return false;
}


private void savePdf(Path outPath) throws IOException {
    pdDocument.save(outPath.toFile());
    pdDocument.close();
}

private void addImageForField(Path signature, AcroField targetField) throws IOException {
    PDPage page = pdDocument.getPage(targetField.getPageNr() - 1);
    DrawImage image = new DrawImage(Files.readAllBytes(signature), 0, 0);
    PDImageXObject pdImage = PDImageXObject.createFromFile(signature.toAbsolutePath().toString(), pdDocument);

    try(PDPageContentStream contentStream = new PDPageContentStream(pdDocument, page)){
        contentStream.drawImage(pdImage, targetField.getX(), targetField.getY(), targetField.getWidth(), targetField.getHeight());
    }
}



public class ImageData {

private String fieldName;
private Path imagePath;

public ImageData(String fieldName, Path imagePath) {
    this.fieldName = fieldName;
    this.imagePath = imagePath;
}

public String getFieldName() {
    return fieldName;
}

public void setFieldName(String fieldName) {
    this.fieldName = fieldName;
}

public Path getImagePath() {
    return imagePath;
}

public void setImagePath(Path imagePath) {
    this.imagePath = imagePath;
}

}

1 个答案:

答案 0 :(得分:3)

您可以使用

为目标网页创建内容流
PDPageContentStream contentStream = new PDPageContentStream(pdDocument, page)

此构造函数记录为

/**
 * Create a new PDPage content stream. This constructor overwrites all existing content streams
 * of this page.
 *
 * @param document The document the page is part of.
 * @param sourcePage The page to write the contents to.
 * @throws IOException If there is an error writing to the page contents.
 */
public PDPageContentStream(PDDocument document, PDPage sourcePage) throws IOException

因此,使用此构造函数,您将覆盖该页面的所有现有内容流!特别要覆盖以前添加的任何用于绘制另一个图像的说明......

您应该使用不同的构造函数,例如

/**
 * Create a new PDPage content stream. If the appendContent parameter is set to
 * {@link AppendMode#APPEND}, you may want to use
 * {@link #PDPageContentStream(PDDocument, PDPage, PDPageContentStream.AppendMode, boolean, boolean)}
 * instead, with the fifth parameter set to true.
 *
 * @param document The document the page is part of.
 * @param sourcePage The page to write the contents to.
 * @param appendContent Indicates whether content will be overwritten, appended or prepended.
 * @param compress Tell if the content stream should compress the page contents.
 * @throws IOException If there is an error writing to the page contents.
 */
public PDPageContentStream(PDDocument document, PDPage sourcePage, AppendMode appendContent,
                           boolean compress) throws IOException

使用AppendMode.APPENDAppendMode.PREPEND,具体取决于是否应在之前绘制的内容之上或之下绘制新内容。