使用itextpdf 5填充PDF表单

本次使用的是itext pdf5(PDF填充:文本框,图片
参考博客:博客1
推荐使用itext pdf7 (参考博客:https://blog.csdn.net/u012397189/category_6356371.html)

一、制作PDF模板

开始编辑:
先下载万兴PDF编辑器(Wondershare PDFelement Professional 7)破解版

链接:https://pan.baidu.com/s/1eKj0ZErexAwTWrHT9wvG3A 
提取码:jce4 

1.先编辑好word,转为PDF作为模板
2.用此编辑器打开PDF模板
3.选择“表单” > 表单自动识别 > 表单编辑
4.可添加表单
5.修改表单的key值为我们对象中的属性值(对应name,age等,方便填充)
6.保存PDF模板(模板放到项目中也可以读取。我的是上传到了OSS服务器上,用一个url访问PDF模板)
在这里插入图片描述

二、Maven依赖:

<!-- itextpdf5 -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
<!-- hutool工具 -->
<dependency>
  <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.3.5</version>
</dependency>

三、代码:

// pdf模板文件路径(oss) 被填充的PDF
	private final String TEMPLATE_URL = "http://aliyuncs.com/upload/10b3cfc17869a1e55df64c48f7f.pdf";

/**
	 * 下载PDF
	 *
	 * @param vo 请求查询参数
	 * @return String 生成PDF链接
	 */
	@GetMapping("/pdf")
	public void downloadPdf(String phone, HttpServletResponse response) {
		// 查询要插入的数据 只取最新的那条数据
		Optional<LowVoltageResidentElec> voltageOptional = new LambdaQueryChainWrapper<>(lowVoltageResidentElecMapper)
			.eq(LowVoltageResidentElec::getIsDeleted, BladeConstant.DB_NOT_DELETED)
			.eq(LowVoltageResidentElec::getClientMobilePhone, phone)
			.list()
			.stream()
			.max((s1, s2) -> (int) (s1.getUpdateTime().getTime() - s2.getUpdateTime().getTime()));
		if (voltageOptional.isPresent()) {
			LowVoltageResidentElec lowVoltageResidentElec = voltageOptional.get();
			Map<String, Object> data = BeanUtil.beanToMap(lowVoltageResidentElec);
			// 输出pdf文件路径
			String targetPath = "";
			// 设置windows或linux系统文件上传路径
			String fileName = IdUtil.simpleUUID() + ".pdf";
			if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
				log.info("Windows系统...");
				targetPath = customFileConfig.getWindows() + fileName; //   d:/测试.pdf
			} else {
				log.info("Linux系统...");
				targetPath = customFileConfig.getLinux() + fileName; //    /home/mzp/sg-yc-pj/tmp/测试.pdf
			}
			BaseFont baseFont = null;
			try {
				// 字体:宋体
				baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
			} catch (Exception e) {
				throw new RuntimeException("本地字体读取有误!");
			}
			PdfReader pdfReader = null;
			PdfStamper pdfStamper = null;
			try {
				URL url = new URL(TEMPLATE_URL);
				pdfReader = new PdfReader(url);
				pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(targetPath));
			} catch (Exception e) {
				throw new RuntimeException("模板读取有误!");
			}

			AcroFields form = pdfStamper.getAcroFields();
			form.addSubstitutionFont(baseFont);
			// 写入数据 用电信息
			try {
				form.setField("clientName", data.get("clientName").toString());
				form.setField("clientIdCard", data.get("clientIdCard").toString());
				form.setField("clientElecAddress", data.get("clientElecAddress").toString());
			} catch (Exception e) {
				throw new RuntimeException("写入数据有误!");
			}

			// 服务评价信息 一个业务员对应一个客户
			Optional<ServiceEvaluation> evaluationOptional = new LambdaQueryChainWrapper<>(serviceEvaluationMapper)
				.eq(ServiceEvaluation::getIsDeleted, BladeConstant.DB_NOT_DELETED)
				.eq(ServiceEvaluation::getEvaluationMobile, phone)
				.list()
				.stream()
				.max((s1, s2) -> (int) (s1.getUpdateTime().getTime() - s2.getUpdateTime().getTime()));
			ServiceEvaluation serviceEvaluation = null;
			if (evaluationOptional.isPresent()) {
				serviceEvaluation = evaluationOptional.get();
				serviceEvaluation.setPicLink(vo.getPicUrl());
				serviceEvaluationService.updateById(serviceEvaluation);
				// 添加图片1 手签图片
				int pageNo = form.getFieldPositions("manuallySignedUrl1").get(0).page;
				Rectangle signRect = form.getFieldPositions("manuallySignedUrl1").get(0).position;
				float x = signRect.getLeft();
				float y = signRect.getBottom();
				// 添加图片2 手签图片
				int pageNo2 = form.getFieldPositions("manuallySignedUrl2").get(0).page;
				Rectangle signRect2 = form.getFieldPositions("manuallySignedUrl2").get(0).position;
				float x2 = signRect2.getLeft();
				float y2 = signRect2.getBottom();

				Image image = null;
				Image image2 = null;
				try {
					// 写入图片1
					image = Image.getInstance(serviceEvaluation.getManuallySignedUrl());
					PdfContentByte under = pdfStamper.getOverContent(pageNo);
					// 设置图片大小
					image.scaleAbsolute(signRect.getWidth(), signRect.getHeight());
					// 设置图片位置
					image.setAbsolutePosition(x, y);
					under.addImage(image);

					// 写入图片2
					image2 = Image.getInstance(serviceEvaluation.getManuallySignedUrl());
					PdfContentByte under2 = pdfStamper.getOverContent(pageNo2);
					// 设置图片大小
					image2.scaleAbsolute(signRect2.getWidth(), signRect2.getHeight());
					// 设置图片位置
					image2.setAbsolutePosition(x2, y2);
					under2.addImage(image2);
				} catch (Exception e) {
					throw new RuntimeException("写入手签图片有误!");
				}
			} else {
				log.info("手签图片未写入PDF");
			}

			//设置不可编辑, pdfStamper.close()后PDF生成
			pdfStamper.setFormFlattening(true);
			try {
				pdfStamper.close();
			} catch (Exception e) {
				throw new RuntimeException("PDF对象关闭有误!");
			}	
	}

四、效果:

和普通PDF一样。
谷歌浏览器打开字体有问题,需要用wps打开就好了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值