第一步模板制作:
在word中先把模板画好,另存为pdf,具体步骤为:wps—》工具------》开发工具。如图所示图片也是设置为文本域,千万不要设置为图片域,否则图片会被覆盖!
图片也是设置为文本域,千万不要设置为图片域,否则图片会被覆盖!
图片也是设置为文本域,千万不要设置为图片域,否则图片会被覆盖!
准备好模板后下载adobe2024
获取破解安装包v: yzb328899或v众号 T96虚拟资料吧 发送adobe获取,也可自行下载。
安装好adobe后打开刚刚保存的模板,在adobe中打开准备表单。如下图所示:定义模板中的每一个字段名称,包括样式字段的字体大小颜色和其他的属性如下图所示
JAVA中的map或者实体对象命名时字段名必须与这里保持一致!
JAVA中的map或者实体对象命名时字段名必须与这里保持一致!
JAVA中的map或者实体对象命名时字段名必须与这里保持一致!
操作复选框
定义属性,定义选中时的形状
如何选中复选框?当参数传递“导出值”时即为选中,如下图所示
JAVA中设置选中,这里要设置为true,否则是相反的,选中为x,只有设置为true时选中才是√。
form.setField("toggle1", "Y",true); form.setField("toggle2", "Yes",true); form.setField("toggle3", "On",true);
结果如图所示:
接下来开始代码实现,直奔主题!!!
添加maven依赖 <!-- itextpdf的亚洲字体支持 --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency> <!--itextpdf--> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency> <!--生成二维码--> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.4.1</version> </dependency>
将准备好的pdf模板放入项目中的resource----》static-------》template目录。若没有此目录则自己创建如图所示:
表单内容实体类Entity Or Domain
import lombok.Data;@Datapublic class PaymentOrder { /** * 年 */ private String year; /** *月 */ private String month; /** *日 */ private String day; /** *付款 */ private String toggle1; /** *支票 */ private String toggle2; /** *转账 */ private String toggle3; /** *收款账号 */ private String acount; /** *人民币大写 */ private String CNY; /** *人民币数值 */ private String cnyNum; /** * 二维码 */ private String QRCode; /** * 图片 */ private String photo; /** *备注 */ private String remark;}
Controller层代码实现: @GetMapping("/test") public void generateForm(HttpServletResponse response,PaymentOrder paymentOrder ){ //此处模拟前端传来的数据,或查询数据库获得的数据 paymentOrder.setAcount("1111"); paymentOrder.setCNY("壹佰万"); paymentOrder.setYear("2024"); paymentOrder.setMonth("07"); paymentOrder.setDay("22"); //图片绝对路径 paymentOrder.setPhoto("C:\\Users\\Administrator\\Desktop\\goods\\ruoyi-system\\src\\main\\resources\\static\\img.png"); paymentOrder.setRemark("测试一下"); paymentOrder.setCnyNum("1000000"); paymentOrder.setToggle1("Y"); paymentOrder.setToggle3("Y"); //二维码内容 paymentOrder.setQRCode("https://blog.csdn.net/m0_46523467?spm=1000.2115.3001.5343"); //pdf模板存放路径 String templatePath="C:\\Users\\Administrator\\Desktop\\goods\\ruoyi-system\\src\\main\\resources\\static\\template\\payment_order_template.pdf"; //生成后的文件存放路径 String outPutPath="C:\\Users\\Administrator\\Desktop\\goods\\ruoyi-system\\src\\main\\resources\\static\\payment_order.pdf"; logisticsService.generateForm(response,paymentOrder,templatePath,outPutPath); }
service 层 /** * 报表生成 * @param response * @param paymentOrder * @param templatePath * @param outputPath */ void generateForm(HttpServletResponse response, PaymentOrder paymentOrder,String templatePath,String outputPath);}
serviceImpl /** * 报表生成 * @param response * @param paymentOrder */ @Override public void generateForm(HttpServletResponse response, PaymentOrder paymentOrder, String template_path, String output_path) { //表单中的文本数据map Map<String,String> form=new HashMap<>(); //表单中图片map Map<String,String> image=new HashMap<>(); //表单中二维码图片生成内筒map Map<String,String> qrcode=new HashMap<>(); //表单内容 form.put("year",paymentOrder.getYear()); form.put("month",paymentOrder.getMonth()); form.put("day",paymentOrder.getDay()); form.put("acount",paymentOrder.getAcount()); form.put("CNY",paymentOrder.getCNY()); form.put("toggle1",paymentOrder.getToggle1()); form.put("toggle2",paymentOrder.getToggle2()); form.put("toggle3",paymentOrder.getToggle3()); form.put("cnyNum",paymentOrder.getCnyNum()); form.put("remark",paymentOrder.getRemark()); //图片 image.put("photo", paymentOrder.getPhoto()); //二维码的内容 qrcode.put("QRCode",paymentOrder.getQRCode()); /**填充表单内容,width为二维码的宽,height为二维码的高,如没有二维二维码和图片则传null,宽和高传0。 *fillPdfTemplate(String templateUrl, String outputFileUrl, Map<String, String> fieldMap, *Map<String, String> imageMap, Map<String, String> QRCodeMap,int width,int height) */ PDFUtils.fillPdfTemplate(template_path,output_path,form,image,qrcode,300,300);
自定义PDF工具类 import com.itextpdf.text.DocumentException;import com.itextpdf.text.Image;import com.itextpdf.text.Rectangle;import com.itextpdf.text.pdf.*;import lombok.extern.slf4j.Slf4j;import java.io.File;import java.io.IOException;import java.io.OutputStream;import java.lang.reflect.Field;import java.nio.file.Files;import java.util.HashMap;import java.util.Map;@Slf4jpublic final class PDFUtils { public static boolean fillPdfTemplate(String templateUrl, String outputFileUrl, Map<String, String> fieldMap, Map<String, String> imageMap, Map<String, String> QRCodeMap,int width,int height) { boolean success = true; OutputStream os = null; PdfStamper ps = null; PdfReader reader = null; AcroFields form = null; try { os = Files.newOutputStream(new File(outputFileUrl).toPath()); reader = new PdfReader(templateUrl); ps = new PdfStamper(reader, os); form = ps.getAcroFields(); // 添加中文字体支持(可选) BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); form.addSubstitutionFont(bf); // 填充表单字段 for (Map.Entry<String, String> entry : fieldMap.entrySet()) { if(entry.getValue()!=null){ form.setField(entry.getKey(), entry.getValue(),true); } } // 插入图片 for (Map.Entry<String, String> entry : imageMap.entrySet()) { if (entry.getValue()!=null){ insertImage(form, ps, entry.getKey(), entry.getValue()); } } // 插入二维码 for (Map.Entry<String, String> entry : QRCodeMap.entrySet()) { if(width!=0&&height!=0){ insertQRCodeImage(form, ps,entry.getKey(), entry.getValue(), width,height); } } } catch (Exception e) { success = false; e.printStackTrace(); // 可以根据实际情况处理异常 } finally { try { if (ps != null) ps.close(); if (reader != null) reader.close(); if (os != null) os.close(); } catch (IOException | DocumentException e) { throw new RuntimeException(e); } finally { System.out.println("文件导出完成!"); } } return success; } //插入图片的函数,fieldName为字段名,imageUrl为图片路径 private static void insertImage(AcroFields form, PdfStamper ps, String fieldName,String imageUrl) throws IOException, DocumentException { if(imageUrl!=null){ //获取fieldName所在的页码 int pageNo = form.getFieldPositions(fieldName).get(0).page; Rectangle signRect = form.getFieldPositions(fieldName).get(0).position; float x = signRect.getLeft(); float y = signRect.getBottom(); Image image = Image.getInstance(imageUrl); // 获取操作的页面 PdfContentByte overContent = ps.getOverContent(pageNo); // 根据域的大小缩放图片 image.scaleToFit(signRect.getWidth(), signRect.getHeight()); // 添加图片 image.setAbsolutePosition(x, y); overContent.addImage(image); ps.setFormFlattening(true); } } //生成二维码图片并插入图片的函数 private static void insertQRCodeImage(AcroFields form, PdfStamper ps, String fieldName, String qrCodeUrl,int width,int height) throws IOException, DocumentException { if(qrCodeUrl!=null&&!qrCodeUrl.equals("")){ int pageNo = form.getFieldPositions(fieldName).get(0).page; Rectangle signRect = form.getFieldPositions(fieldName).get(0).position; float x = signRect.getLeft(); float y = signRect.getBottom(); // 生成二维码 BarcodeQRCode barcodeQRCode=new BarcodeQRCode(qrCodeUrl,width,height,null); Image image = barcodeQRCode.getImage(); // 获取操作的页面 PdfContentByte overContent = ps.getOverContent(pageNo); // 根据域的大小缩放图片 image.scaleToFit(signRect.getWidth(), signRect.getHeight()); // 添加二维码图片到pdf中 image.setAbsolutePosition(x, y); overContent.addImage(image); ps.setFormFlattening(true); } }}
实现结果: