写这个纯属是为了总结最近所学的知识,也是为了给后面用的到人的一些帮助。因为自己在国内查找了不少资料,但都不是自己想要的。
背景:创建合同时,需要填写某些文本域、radio、checkbox还有最后需要对合同签名,所以需要研究使用,而不是采用外部编辑器。
itext简介
iText是一种生成PDF报表的Java组件。通过在服务器端使用Jsp或JavaBean生成PDF报表
因为itext版本太多,我这里采用的是5.5.3,只供读者参考。
表单域
完整项目代码以及jar包,包含详细介绍:http://download.csdn.net/download/qiumeng_1314/10217825
这里给出官方api创造pdf表单域的例子的链接,大家可以前去查看。
https://developers.itextpdf.com/examples/form-examples-itext5/creating-form-fields
查看例子后发现,无法符合我的需求,我是读取上传的pdf模板,并修改其表单域,在写入到新的文件中,可以理解为
读取a——操作a的副本--写入b
PdfStamper很好的解决了这一问题,我们看看api的介绍
Applies extra content to the pages of a PDF document. This extra content can be all the objects allowed in PdfContentByte including pages from other Pdfs. The original PDF will keep all the interactive elements including bookmarks, links and form fields.
//test为源文件流 理解为上文的文件a
PdfReader reader = new PdfReader(dest);
//outputStream 理解为上文的文件b
PdfStamper stamper = new PdfStamper(reader, outputStream
);
text域
public static void creatTextField(PdfStamper pdfStamper, PdfReader reader) throws IOException, DocumentException {
PdfWriter writer = pdfStamper.getWriter();
PdfFormField form = PdfFormField.createEmpty(writer);
//普通文本框
TextField field = new TextField(writer, new Rectangle(200, 200, 400, 300), "text");
field.setOptions(TextField.MULTILINE);
//防止读取pdf文档时,就是有旋转角度的
field.setRotation(reader.getPageRotation(1));
//有些情况下,页数问题可以在这里设置,优先级最高
field.getTextField().setPlaceInPage(1);
form.addKid(field.getTextField());
// file.setOptions(TextField.VISIBLE);//文本域可见(相对于文本域是否高亮)
// file.setOptions(TextField.HIDDEN);//文本域不可见
// file.setOptions(TextField.VISIBLE_BUT_DOES_NOT_PRINT);//该字段可见,但不打印。
// file.setOptions(TextField.HIDDEN_BUT_PRINTABLE);//该字段不可见,但不打印。
// file.setOptions(TextField.HIDDEN_BUT_PRINTABLE);//该字段不可见,但不打印。
// file.setOptions(TextField.READ_ONLY);//只读
// file.setOptions(TextField.REQUIRED);//该字段在通过提交表单操作导出时必须具有值。
// file.setOptions(TextField.MULTILINE);//规定区域内可以换行显示
// file.setOptions(TextField.DO_NOT_SCROLL);//文本域不会有滚动条,对于单行字段为水平,对于多行字段为垂直,一旦区域满了,将不会再接受任何文字。
// file.setOptions(TextField.PASSWORD);//该字段用于输入安全密码,该密码不应该被可视地显示在屏幕上。
// file.setOptions(TextField.FILE_SELECTION);//个人理解好像是上传文件,不是很理解
// file.setOptions(TextField.DO_NOT_SPELL_CHECK);//无拼写检查
// file.setOptions(TextField.EDIT);//如果设置组合框包括一个可编辑的文本框以及一个下拉列表;如果清楚,它只包括一个下拉列表。这个标志只对组合字段有意义。
// file.setOptions(TextField.MULTISELECT);//不管列表是否可以有多个选择。仅适用于/ ch列表字段,而不适用于组合框。
// file.setOptions(TextField.COMB);//组合框标志。
pdfStamper.addAnnotation(form,1);
}
radio
需要注意的是,radio是一组一组的。
public static void creatRadioCheckField(PdfStamper pdfStamper,PdfReader reader) throws IOException, DocumentException {
PdfWriter writer = pdfStamper.getWriter();
//radio框
// PdfFormField radioForm=PdfFormField.createRadioButton(writer, true);
PdfFormField radiogroup=PdfFormField.createRadioButton(writer, true);
radiogroup.setFieldName("test");
RadioCheckField bt=new RadioCheckField(writer, new Rectangle(100, 500, 120, 518), null, "v1");
// bt.setCheckType(RadioCheckField.TYPE_CROSS);//X型
// bt.setCheckType(RadioCheckField.TYPE_DIAMOND);//菱形
// bt.setCheckType(RadioCheckField.TYPE_SQUARE);//正方形
// bt.setCheckType(RadioCheckField.TYPE_STAR);//星星图案
// checkField.setCheckType(RadioCheckField.TYPE_CHECK);//checkbox
bt.setCheckType(RadioCheckField.TYPE_CIRCLE);//圆型 radio
bt.setBackgroundColor(new GrayColor(0.8f));//这个颜色看起来比较舒服,建议只采用设置背景颜色
// bt.setChecked(true);//设置radio是否被选中
PdfFormField f1 = bt.getRadioField();
f1.setPlaceInPage(1);
radiogroup.addKid(f1);
RadioCheckField bt3=new RadioCheckField(writer, new Rectangle(100, 300, 120, 318), null, "v3");
bt3.setCheckType(RadioCheckField.TYPE_CIRCLE);//圆型 radio
bt3.setBackgroundColor(new GrayColor(0.8f));
// bt2.setChecked(false);
PdfFormField f3 = bt3.getRadioField();
radiogroup.addKid(f3);
RadioCheckField bt2=new RadioCheckField(writer, new Rectangle(100, 400, 120, 418), null, "v2");
bt2.setCheckType(RadioCheckField.TYPE_CIRCLE);//圆型 radio
bt2.setBackgroundColor(new GrayColor(0.8f));
// bt2.setChecked(false);
PdfFormField f2 = bt2.getRadioField();
radiogroup.addKid(f2);
pdfStamper.addAnnotation(radiogroup,1);
}
button
使用比较少
public static void creatPushbuttonField(PdfStamper pdfStamper) throws IOException, DocumentException {
PdfWriter writer = pdfStamper.getWriter();
//使表单不再可写,也就是禁用表单了
pdfStamper.setFormFlattening(true);
pdfStamper.setFreeTextFlattening(true);
PdfFormField form = PdfFormField.createPushButton(writer);
PushbuttonField button = new PushbuttonField(writer, new Rectangle(100, 100, 200, 200), "Button1");
button.setText(JAPANESE);
button.setFontSize(0);
// button.setImage(Image.getInstance("image.png"));
button.setLayout(PushbuttonField.LAYOUT_ICON_TOP_LABEL_BOTTOM);
button.setBackgroundColor(new BaseColor(0, 255, 255));
// button.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
// button.setBorderColor( new BaseColor(255, 0, 0));
// button.setBorderWidth(3);
PdfFormField buttonFormField = button.getField();
// buttonFormField.setAction(PdfAction.createSubmitForm("http://www.baidu.com", null, 0));
// buttonFormField.setAction(PdfAction.createSubmitForm("http://www.baidu.com", null, 0));
form.addKid(buttonFormField);
pdfStamper.addAnnotation(form,1);
}
表单域赋值
文本域赋值 text文本域名字,aa是展现在pdf文档上文本域中的内容
docData.put("text","aa")
radio赋值 text为radio组名字,aa为一组radio其中一个radio域名字,填写后,在pdf即此radio勾选
docData.put("text","aa")
checkbox赋值 text为checkbox域名字,添加 “Yes” 或“Off”,表示勾选和不勾选
docData.put("text","Yes")
去除表单域
public static void main(String[] args) {
FileOutputStream out= null;
PdfReader reader=null;
PdfStamper pdfStamper=null;
try {
out = new FileOutputStream(new File(second));
reader=new PdfReader(new FileInputStream(new File(save)));
pdfStamper=new PdfStamper(reader,out);
AcroFields s = pdfStamper.getAcroFields();
Map<String, AcroFields.Item> acroFieldMap=s.getFields();
Set<String> keySet = acroFieldMap.keySet();
Object[] keySetStr = keySet.toArray();
for (Object s1 : keySetStr) {
s.removeField(s1.toString());
}
pdfStamper.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
PDF TO Image
public static void Pdf_Png(int pageNumber,String desk,String target ) {
int pagen= pageNumber;
File file = new File(DEST);
PDFFile pdffile=null;
// set up the PDF reading
try{
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
buf.clear();
byte[] b = new byte[buf.capacity()];
buf.get(b, 0, b.length);
// FileOutputStream outputStream =new FileOutputStream("F:\\公司相关资料\\pdf\\test2.pdf");
// outputStream.write(b);
// outputStream.close();
pdffile = new PDFFile(buf);
} catch(Exception e){
e.printStackTrace();
}
if(pagen<pdffile.getNumPages())
return;
//print出该pdf文档的页数
System.out.println(pdffile.getNumPages());
//设置将第pagen也生成png图片
PDFPage page = pdffile.getPage(pagen);
// create and configure a graphics object
int width = (int)page.getBBox().getWidth();
int height =(int)page.getBBox().getHeight();
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// do the actual drawing
PDFRenderer renderer = new PDFRenderer(page, g2,
new Rectangle(0, 0, width, height), null, Color.RED);
try{
page.waitForFinish();
}catch(Exception e){
e.printStackTrace();
}
renderer.run();
g2.dispose();
try{
ImageIO.write(img, "png", new File(target));
}
catch(Exception ex){
ex.printStackTrace();
}
}