第一步模板制作:
- 在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;
@Data
public 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;
@Slf4j
public 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);
}
}
}
实现结果: