我已经创建了简单的PDF文件与3个标签:名,姓和照片。然后我使用Adobe Acrobat PRO DC添加了带有2个“文本字段”和一个“图像字段”的AcroForm层。
因此,如果我想要填写表格,我可以打开这个PDF文件在常规Acrobat Reader和填写,输入名字,姓氏和为了插入照片,我点击图像占位符和选择照片打开的对话框窗口。
但我如何以编程方式完成同样的事情呢?创建了使用Apache PDFBox库(版本2.0.7)查找表单字段并插入值的简单Java应用程序。
我可以很容易地填充文本编辑字段,但不知道如何插入图像:
public class AcroFormPopulator {
public static void main(String[] args) {
AcroFormPopulator abd = new AcroFormPopulator();
try {
abd.populateAndCopy("test.pdf", "generated.pdf");
} catch (IOException e) {
e.printStackTrace();
}
}
private void populateAndCopy(String originalPdf, String targetPdf) throws IOException {
File file = new File(originalPdf);
PDDocument document = PDDocument.load(file);
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
Map<String, String> data = new HashMap<>();
data.put("firstName", "Mike");
data.put("lastName", "Taylor");
data.put("photo_af_image", "photo.jpeg");
for (Map.Entry<String, String> item : data.entrySet()) {
PDField field = acroForm.getField(item.getKey());
if (field != null) {
if (field instanceof PDTextField) {
field.setValue(item.getValue());
} else if (field instanceof PDPushButton) {
File imageFile = new File(item.getValue());
PDPushButton pdPushButton = (PDPushButton) field;
// do not see way to isert image
} else {
System.err.println("No field found with name:" + item.getKey());
}
} else {
System.err.println("No field found with name:" + item.getKey());
}
}
document.save(targetPdf);
document.close();
System.out.println("Populated!");
}
}
我区分了一个奇怪的事情--在Acrobat Pro DC中,它说我添加了Image字段,但我得到的唯一一个字段是生成的名称:'Photo_AF_Image'的类型是Button-PDPushButton'(这就是为什么我检查if(Field instanceof PDPushButton)),但与Image无关。
我如何插入图像到AcroForm的“photo_af_image”字段,以便它将适合创建的af Acrobat Pro DC框的大小?
我终于找到并建立了很好的解决方案。此解决方案的目标是:
下面通过acroForm占位符插入图像的解决方案的主要思想是:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.interactive.action.PDAction;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionHide;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDPushButton;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextField;
public class AcroFormPopulator {
public static void main(String[] args) {
AcroFormPopulator abd = new AcroFormPopulator();
try {
Map<String, String> data = new HashMap<>();
data.put("firstName", "Mike");
data.put("lastName", "Taylor");
data.put("dateTime", (new Date()).toString());
data.put("photo_af_image", "photo1.jpg");
data.put("photo2_af_image", "photo2.jpg");
data.put("photo3_af_image", "photo3.jpg");
abd.populateAndCopy("test.pdf", "generated.pdf", data);
} catch (IOException e) {
e.printStackTrace();
}
}
private void populateAndCopy(String originalPdf, String targetPdf, Map<String, String> data) throws IOException {
File file = new File(originalPdf);
PDDocument document = PDDocument.load(file);
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
for (Map.Entry<String, String> item : data.entrySet()) {
String key = item.getKey();
PDField field = acroForm.getField(key);
if (field != null) {
System.out.print("Form field with placeholder name: '" + key + "' found");
if (field instanceof PDTextField) {
System.out.println("(type: " + field.getClass().getSimpleName() + ")");
field.setValue(item.getValue());
System.out.println("value is set to: '" + item.getValue() + "'");
} else if (field instanceof PDPushButton) {
System.out.println("(type: " + field.getClass().getSimpleName() + ")");
PDPushButton pdPushButton = (PDPushButton) field;
List<PDAnnotationWidget> widgets = pdPushButton.getWidgets();
if (widgets != null && widgets.size() > 0) {
PDAnnotationWidget annotationWidget = widgets.get(0); // just need one widget
String filePath = item.getValue();
File imageFile = new File(filePath);
if (imageFile.exists()) {
/*
* BufferedImage bufferedImage = ImageIO.read(imageFile);
* PDImageXObject pdImageXObject = LosslessFactory.createFromImage(document, bufferedImage);
*/
PDImageXObject pdImageXObject = PDImageXObject.createFromFile(filePath, document);
float imageScaleRatio = (float) pdImageXObject.getHeight() / (float) pdImageXObject.getWidth();
PDRectangle buttonPosition = getFieldArea(pdPushButton);
float height = buttonPosition.getHeight();
float width = height / imageScaleRatio;
float x = buttonPosition.getLowerLeftX();
float y = buttonPosition.getLowerLeftY();
PDAppearanceStream pdAppearanceStream = new PDAppearanceStream(document);
pdAppearanceStream.setResources(new PDResources());
try (PDPageContentStream pdPageContentStream = new PDPageContentStream(document, pdAppearanceStream)) {
pdPageContentStream.drawImage(pdImageXObject, x, y, width, height);
}
pdAppearanceStream.setBBox(new PDRectangle(x, y, width, height));
PDAppearanceDictionary pdAppearanceDictionary = annotationWidget.getAppearance();
if (pdAppearanceDictionary == null) {
pdAppearanceDictionary = new PDAppearanceDictionary();
annotationWidget.setAppearance(pdAppearanceDictionary);
}
pdAppearanceDictionary.setNormalAppearance(pdAppearanceStream);
System.out.println("Image '" + filePath + "' inserted");
} else {
System.err.println("File " + filePath + " not found");
}
} else {
System.err.println("Missconfiguration of placeholder: '" + key + "' - no widgets(actions) found");
}
} else {
System.err.print("Unexpected form field type found with placeholder name: '" + key + "'");
}
} else {
System.err.println("No field found with name:" + key);
}
}
// you can optionally flatten the document to merge acroform lay to main one
acroForm.flatten();
document.save(targetPdf);
document.close();
System.out.println("Done");
}
private PDRectangle getFieldArea(PDField field) {
COSDictionary fieldDict = field.getCOSObject();
COSArray fieldAreaArray = (COSArray) fieldDict.getDictionaryObject(COSName.RECT);
return new PDRectangle(fieldAreaArray);
}
}
请让我知道,如果有更好的解决方案或您可以改进的代码。
问题内容: 我想在Java中动态地做到这一点。我知道如何在单维数组中插入值。我对二维数组有些困惑。 问题答案:
问题内容: 因此,我基本上希望能够触发一个事件,然后进行伪指令编译并将其自身插入DOM中的某个位置。目前我有这样的事情 我可以看到具有所有所需内容的“ el”对象,但无法将其插入到DOM中……有什么线索吗? 问题答案: 您必须先创建dom元素,然后对其进行编译并将其添加到文档中。像这样: 我在这里创建了一个简单的示例:http : //plnkr.co/edit/n7SZpyeQ9nbjVSYA7
我有一个mp4文件,其中视频的背景颜色为纯色,如白色/绿色/蓝色。我想改变背景颜色。请让我知道如何改变颜色编程使用Android.
我需要在我的工作区中以编程方式导入一个. jar文件,就像我使用菜单时一样:< br> Import - 在这里,我找到了导入java项目的代码:< br > IProject描述描述 = ResourcesPlugin.getWorkspace().loadProject描述(新路径(“PROJECT_PATH/.项目”);( IProject project = ResourcesPlugin
问题内容: 如何以编程方式在HTML 字段中选择特定范围的文本?(我不想选择 整个 字段,而只是选择一个子集) 另外,如何确定字段中当前选择的范围? 问题答案: 以下是选择文本框的一部分(范围选择)并获取所选文本的方法:
我想以编程方式创建3x3网格视图以显示图像。我想通过获取屏幕尺寸来设置每个项目的高度和宽度。像: 然后每个项目 请有人帮助我或一些参考链接。