我尝试使用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;
}
}
答案 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.APPEND
或AppendMode.PREPEND
,具体取决于是否应在之前绘制的内容之上或之下绘制新内容。