一、java按照模板导出pdf
(一)制作模板
1、在word里制作模板
因为PDF常用的软件不支持编辑,所以先用Word工具,如WPS或者Office新建一个空白Word文档,里面制作出自己想要的样式。
将Word转换成PDF形式
将设置好的Word文档转换成PDF形式,保存起来。
编辑PDF准备表单
用Adobe Acrobat DC 软件打开保存好的PDF模板文件,点击右侧的准备表单按钮
接下来进行数据源配置,在要显示图像的区域,点击鼠标右键,选择文本域,设定好图像的显示位置,并指定数据源字段。需要注意的是,配置的数据源字段必须与Java中的实体类对象的字段名保持一致。
配置完成之后保存pdf文件,留作模板使用。
(二)java代码编写
导入依赖
com.itextpdf itextpdf 5.5.13 com.itextpdf itext-asian 5.2.0
实体类
import lombok.Data;@Datapublic class MsaBusinessVO { private String total; private String lastToatl; private String dealNum; private String lastDealNum; private String completeNum; private String lastCompleteNum; private String afterSales; private String lastAfterSales;}
service层代码实现
void generateMsaBusiness(String id,HttpServletResponse response) throws UnsupportedEncodingException;
@Overridepublic void generateMsaBusiness(String id,HttpServletResponse response) throws UnsupportedEncodingException { //通过id获取msaBusinessVO MsaBusinessVO msaBusinessVO = msaBusinessDao.getMsaBusinessInfo(id); // 模板名称 String templateName = "msaBusiness.pdf"; String path = "/static/template/"; //String path = ""; // 获取操作系统名称,根据系统名称确定模板存放的路径 // 生成导出PDF的文件名称 String fileName = "海事行政执法业务数据统计"+msaBusinessVO.getStartDate()+"至"+msaBusinessVO.getEndDate()+".pdf"; fileName = URLEncoder.encode(fileName, "UTF-8"); // 设置响应头 response.setContentType("application/force-download"); response.setHeader("Content-Disposition", "attachment;fileName=" + fileName); OutputStream out = null; ByteArrayOutputStream bos = null; PdfStamper stamper = null; PdfReader reader = null; try { // 保存到本地 // out = new FileOutputStream(fileName); // 输出到浏览器端 out = response.getOutputStream(); // 读取PDF模板表单 reader = new PdfReader(path + templateName); // 字节数组流,用来缓存文件流 bos = new ByteArrayOutputStream(); // 根据模板表单生成一个新的PDF stamper = new PdfStamper(reader, bos); // 获取新生成的PDF表单 AcroFields form = stamper.getAcroFields(); // 给表单生成中文字体,这里采用系统字体,不设置的话,中文显示会有问题 //BaseFont font = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); BaseFont bf = BaseFont.createFont("/static/fonts/simsun.ttc,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); form.addSubstitutionFont(bf); // 装配数据 this.setMsaBusinessToForm(form, msaBusinessVO); // 表明该PDF不可修改 stamper.setFormFlattening(true); // 关闭资源 stamper.close(); // 将ByteArray字节数组中的流输出到out中(即输出到浏览器) Document doc = new Document(); PdfCopy copy = new PdfCopy(doc, out); doc.open(); //改成这样就不会只显示一页了。 PdfImportedPage importPage = null; ///循环是处理成品只显示一页的问题 for (int i=1;i<=reader.getNumberOfPages();i++){ importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), i); copy.addPage(importPage); } doc.close(); log.info("*****************************PDF导出成功*********************************"); } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null) { out.flush(); out.close(); } if (reader != null) { reader.close(); } } catch (Exception e) { e.printStackTrace(); } }}public void setMsaBusinessToForm(AcroFields form,MsaBusinessVO msaBusinessVO) throws DocumentException, IOException { form.setField("total",msaBusinessVO.getTotal());//进出港船舶总艘次 form.setField("lastTotal",msaBusinessVO.getLastTotal());//进出港船舶总艘次(去年同期) form.setField("dealNum",msaBusinessVO.getDealNum());//进出港报告内河船艘次 form.setField("lastDealNum",msaBusinessVO.getLastDealNum());//进出港报告内河船艘次(去年同期) form.setField("completeNum",msaBusinessVO.getCompleteNum());//进出港报告海船艘次 form.setField("lastCompleteNum",msaBusinessVO.getLastCompleteNum());//进出港报告海船艘次(去年同期) form.setField("afterSales",msaBusinessVO.getAfterSales());//进出口岸查验船舶艘次 form.setField("lastAfterSales",msaBusinessVO.getLastAfterSales());//进出口岸查验船舶艘次(去年同期)}
Controller层代码实现
@GetMapping("/generateMsaBusiness")public void generateMsaBusiness(String id,HttpServletResponse response){ try { msaBusinessService.generateMsaBusiness(id,response); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }}
二、java按照模板导出word
(一)制作模板
word模板文件处理,如下图所示在word 文档中填值的地方写入占位变量,值得注意的是,word中的占位变量要与java代码中写入的元素名称保持一致。
2、将word文档另存为xml文件,编辑如下图,找到填写的占位,修改为${total}格式
3、将文件后缀名改为.ftl文件 ,留作模板使用。
(二)java代码编写
引入依赖
org.freemarker freemarker 2.3.28 compile
service层代码实现
void exportSimpleWord(Map param);
@Override@Transactional(rollbackFor = Exception.class)public void exportSimpleWord(Map param){ //param.put("total",total); //param.put("lastTotal",lastTotal); try { // 要填充的数据 dataMap, 注意map的key要和word中${xxx}的xxx一致 //Configuration用于读取ftl文件 Configuration configuration = new freemarker.template.Configuration(Configuration.VERSION_2_3_23); System.out.println(configuration.getVersion()); configuration.setDefaultEncoding("utf-8"); //指定路径的第一种方式(根据某个类的相对路径指定) configuration.setClassForTemplateLoading(this.getClass(), "/static/template/"); // 输出文档路径及名称 File outFile = new File("D:/附件"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+".doc"); //以utf-8的编码读取ftl文件 名字要正确,最好不要放在本地,可能会出现找不到。 Template t1 = configuration.getTemplate("unpackCheck.ftl", "utf-8"); // Template t = configuration.getTemplate("a.ftl","utf-8"); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240); t1.process(param, out); out.close(); }catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); }}
Controller层代码实现
@PostMapping("/exportSimpleWord")public void exportSimpleWord(@RequestBody Map param) { dangerCompareService.exportSimpleWord(param);}
来源地址:https://blog.csdn.net/weixin_40052304/article/details/130859464