java根据模板导出PDF(利用itext)
一、制作模板
1.下载Adobe Acrobat 9 Pro软件(pdf编辑器),制作模板必须使用该工具。
2.下载itextpdf-5.5.5.jar、itext-asian-5.2.0.jar两个jar包。(说明:itextpdf-5.5.5.jar用于操作pdf;itext-asian-5.2.0.jar用于pdf中文处理)
3.新建word文档,根据项目需求制作模板,然后另存为pdf格式的文件。
4.Adobe Acrobat 9 Pro软件打开pdf模板文件,点击‘‘表单’’--“启动表单向导”--引入pdf模板文件--添加表单域或者在自动识别的表单域设置表单域名称。设置完成后保存pdf模板。
模板设置如图所示:
最终的模板如下所示:
二、java代码
package test; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.AcroFields; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; /** * 根据模板导出pdf(多页) * @author lyc * */ public class TestPdf7 { // 利用模板生成pdf public static void fillTemplate() { // 模板路径 String templatePath = "C:/Users/lyc/Desktop/proposalTemplate8.pdf"; // 生成的新文件路径 String newPDFPath = "C:/Users/lyc/Desktop/ceshi111.pdf"; PdfReader reader; FileOutputStream out; ByteArrayOutputStream bos; PdfStamper stamper; try { out = new FileOutputStream(newPDFPath);// 输出流 reader = new PdfReader(templatePath);// 读取pdf模板 bos = new ByteArrayOutputStream(); stamper = new PdfStamper(reader, bos); AcroFields form = stamper.getAcroFields(); /*使用中文字体 */ /*BaseFont bf = BaseFont.createFont(PDFTicket.class.getResource("/") +"org/csun/ns/util/simsun.ttc,1", BaseFont.IDENTITY_H,BaseFont.EMBEDDED);*/ //BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); BaseFont bf = BaseFont.createFont("C:/Windows/Fonts/simsun.ttc,1", BaseFont.IDENTITY_H,BaseFont.EMBEDDED); ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(); fontList.add(bf); form.setSubstitutionFonts(fontList); //String[] str = { "123456789", "TOP__ONE", "男", "1991-01-01", "130222111133338888", "河北省保定市","nishi" }; //String[] str = { "123456789", "TOP__ONE", "22", "1991-01-01", "130222111133338888", "333","nishi" }; Map<String,Object> map = new HashMap<String,Object>(); init(map); //int i = 0; java.util.Iterator<String> it = form.getFields().keySet().iterator(); while (it.hasNext()) { String name = it.next().toString(); System.out.println(name); //form.setField(name, map.get(name).toString()); form.setField(name, "aa"); } stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true stamper.close(); Document doc = new Document(); PdfCopy copy = new PdfCopy(doc, out); doc.open(); int pageNum = reader.getNumberOfPages(); //pdf模板总页数 for(int i = 1;i <= pageNum;i++){ PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), i); copy.addPage(importPage); } doc.close(); } catch (IOException e) { e.printStackTrace(); System.out.println(1); } catch (DocumentException e) { e.printStackTrace(); System.out.println(2); } } private static void init(Map<String, Object> map) { //String[] str = { "123456789", "刘向南", "男", "1991-01-01", "130222111133338888", "河北省保定市","nishi" }; map.put("reversionId", "0009198181"); map.put("proposalNo", "8324735439"); map.put("proposalStatus", "拒保"); map.put("riskName", "尊享人生"); map.put("baozhang", "20年"); map.put("jiaofei", "趸交"); map.put("jine", "100000美元"); map.put("baofei", "3421美元"); map.put("xing1", "张"); map.put("ming1", "三"); map.put("pinyin", "ZHANG SAN"); map.put("sex", "男"); map.put("xing2", "张"); map.put("ming2", "小六"); map.put("xing3", "张"); map.put("ming3", "三"); map.put("company", "仁福香港保险中介有限公司"); map.put("area", "西北财富管理事业部"); map.put("dept", "第一营业部"); } public static void main(String[] args) { fillTemplate(); } }
导出pdf文件如下所示:
此处是main方法测试,如果应用到web项目中可参考下面的代码(与上面的代码几乎一致,加了响应另存为处理,导出pdf就会出现弹框):
package com.test.www.web.controller; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.AcroFields; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; @RequestMapping("/test1") @Controller public class TestPdfController_c { @RequestMapping("/testpdf") public void testpdf( HttpServletRequest request, HttpServletResponse response, ModelMap map) throws UnsupportedEncodingException{ // 设置响应头,控制浏览器下载该文件 response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("投保单详情.pdf", "UTF-8")); // 模板路径 String templatePath = "C:/Users/lyc/Desktop/proposalTemplate8.pdf"; // 生成的新文件路径 //String newPDFPath = "C:/Users/lyc/Desktop/ceshi5.pdf"; PdfReader reader; //FileOutputStream out; ByteArrayOutputStream bos; PdfStamper stamper; try { //out = new FileOutputStream(newPDFPath);// 输出流 reader = new PdfReader(templatePath);// 读取pdf模板 bos = new ByteArrayOutputStream(); stamper = new PdfStamper(reader, bos); AcroFields form = stamper.getAcroFields(); /*使用中文字体 */ /*BaseFont bf = BaseFont.createFont(PDFTicket.class.getResource("/") +"org/csun/ns/util/simsun.ttc,1", BaseFont.IDENTITY_H,BaseFont.EMBEDDED);*/ //BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); /*BaseFont bf = BaseFont.createFont("C:/Windows/Fonts/simsun.ttc,1", BaseFont.IDENTITY_H,BaseFont.EMBEDDED);*/ /** * PDF Font Name已设为STSong-Light(宋体),在PDF Encoding中已选择GB-UCS2-H(Chinese Simplified); * 导出pdf中文显示问题 */ BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(); fontList.add(bf); form.setSubstitutionFonts(fontList); Map<String,Object> mapInfo = new HashMap<String,Object>(); init(mapInfo); //int i = 0; java.util.Iterator<String> it = form.getFields().keySet().iterator(); while (it.hasNext()) { String name = it.next().toString(); System.out.println(name); //form.setField(name, "aa"); //mapInfo.get(name).toString() form.setField(name, mapInfo.get(name).toString()); } stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true stamper.close(); // 创建输出流 OutputStream out = response.getOutputStream(); Document doc = new Document(); PdfCopy copy = new PdfCopy(doc, out); //PdfWriter.getInstance(doc, out); doc.open(); int pageNum = reader.getNumberOfPages(); //pdf模板总页数 for(int i = 1;i <= pageNum;i++){ PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), i); //第i页 copy.addPage(importPage); } doc.close(); //byte[] content = bos.toByteArray(); //out.write(content); //FileInputStream in = content; /*doc.add(new Paragraph("Hello Kiran")); doc.add(new Paragraph(new Date().toString())); byte[] content = bos.toByteArray();*/ } catch (IOException e) { e.printStackTrace(); System.out.println(1); } catch (DocumentException e) { e.printStackTrace(); System.out.println(2); } } private static void init(Map<String, Object> map) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); //String[] str = { "123456789", "刘向南", "男", "1991-01-01", "130222111133338888", "河北省保定市","nishi" }; map.put("reversionId", "0009198181"); map.put("proposalNo", "8324735439"); map.put("proposalStatus", "拒保"); map.put("riskName", "尊享人生"); map.put("baozhang", "20年"); map.put("jiaofei", "趸交"); map.put("jine", "100000美元"); map.put("baofei", "3421美元"); map.put("xing1", "张"); map.put("ming1", "三"); map.put("pinyin", "ZHANG SAN"); map.put("sex", "男"); map.put("xing2", "张"); map.put("ming2", "小六"); map.put("xing3", "张"); map.put("ming3", "三"); map.put("company", "仁福香港保险中介有限公司"); map.put("area", "西北财富管理事业部"); map.put("dept", "第一营业部"); map.put("date", sdf.format(new Date())); } }