Browse Source

feat:1.新增本地字体路径指定,修改 pdf 拼接表单文本 2.新增订单失效处理接口,新增订单根据用户信息查询 3.新增字典查询

master
tanzs 6 days ago
parent
commit
7034c6f71f
14 changed files with 238 additions and 52 deletions
  1. +3
    -5
      jeecg-module-miniapp/pom.xml
  2. +44
    -0
      jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/dict/controller/DictController.java
  3. +40
    -1
      jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/controller/OrderController.java
  4. +7
    -12
      jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/entity/OrderInfo.java
  5. +7
    -0
      jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/OrderService.java
  6. +55
    -8
      jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/impl/OrderServiceImpl.java
  7. +0
    -1
      jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/product/controller/MProductController.java
  8. +75
    -24
      jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/utils/PdfFormUtils.java
  9. +1
    -1
      jeecg-module-system/jeecg-system-start/pom.xml
  10. +2
    -0
      jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml
  11. +2
    -0
      jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml
  12. +2
    -0
      jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml
  13. BIN
      jeecg-module-system/jeecg-system-start/src/main/resources/fonts/STKAITI.TTF
  14. BIN
      jeecg-module-system/jeecg-system-start/src/main/resources/fonts/simsun.ttc

+ 3
- 5
jeecg-module-miniapp/pom.xml View File

@ -38,15 +38,13 @@
<!-- iText 7 核心库 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-core</artifactId>
<artifactId>itext7-core</artifactId>
<version>8.0.3</version>
<type>pom</type>
</dependency>
<!-- 表单处理模块 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>forms</artifactId>
<version>8.0.3</version>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>


+ 44
- 0
jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/dict/controller/DictController.java View File

@ -0,0 +1,44 @@
package org.jeecg.modules.miniapp.dict.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.system.vo.DictModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @author tanzs
* @date 2025/2/23 17:21
*/
@Api(tags="字典查询")
@RestController
@RequestMapping("/miniapp/dict")
@Slf4j
public class DictController {
@Lazy
@Resource
private CommonAPI commonApi;
/**
* 获取数据字典
* @param code
* @return
*/
@ApiOperation(value="字典code查询", notes="字典code查询")
@GetMapping("/queryDictItemsByCode")
@ApiImplicitParam(name = "code", value = "字典 code", required = true, dataType = "String", paramType = "query")
List<DictModel> queryDictItemsByCode(@RequestParam("code") String code){
return commonApi.queryDictItemsByCode(code);
}
}

+ 40
- 1
jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/controller/OrderController.java View File

@ -15,9 +15,11 @@ import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.query.QueryRuleEnum;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.MLoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.miniapp.order.service.OrderService;
import org.jeecg.modules.miniapp.order.service.impl.OrderServiceImpl;
import org.jeecg.modules.miniapp.utils.UserInfoUtil;
import org.jeecg.modules.sysMiniapp.order.entity.AppOrder;
import org.jeecg.modules.sysMiniapp.order.entity.AppOrderCar;
import org.jeecg.modules.sysMiniapp.order.entity.AppOrderFinance;
@ -66,6 +68,8 @@ public class OrderController {
private IAppOrderFinanceService appOrderFinanceService;
@Autowired
private OrderService orderService;
@Autowired
private UserInfoUtil userInfoUtil;
/**
* 分页列表查询
@ -83,6 +87,8 @@ public class OrderController {
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
// 获取当前用户信息只能查询当前账号订单
MLoginUser userInfo = userInfoUtil.getUserInfo();
// 自定义查询规则
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
// 自定义多选的查询规则为LIKE_WITH_OR
@ -90,6 +96,7 @@ public class OrderController {
customeRuleMap.put("custType", QueryRuleEnum.LIKE_WITH_OR);
customeRuleMap.put("status", QueryRuleEnum.LIKE_WITH_OR);
QueryWrapper<AppOrder> queryWrapper = QueryGenerator.initQueryWrapper(appOrder, req.getParameterMap(),customeRuleMap);
queryWrapper.eq("create_by",userInfo.getNickName());
Page<AppOrder> page = new Page<AppOrder>(pageNo, pageSize);
IPage<AppOrder> pageList = appOrderService.page(page, queryWrapper);
return Result.OK(pageList);
@ -124,7 +131,13 @@ public class OrderController {
@ApiImplicitParam(name = "orderId", value = "订单id", required = true, dataType = "String", paramType = "query"),
})
public Result<String> addContract(@RequestParam(value = "orderId")String orderId) {
AppOrder appOrderEntity = appOrderService.getById(orderId);
// 获取当前用户信息只能生成当前账号订单
MLoginUser userInfo = userInfoUtil.getUserInfo();
QueryWrapper<AppOrder> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("create_by", userInfo.getNickName());
queryWrapper.eq("id",orderId);
queryWrapper.eq("status",0); // 未生效的订单才可以生成
AppOrder appOrderEntity = appOrderService.getOne(queryWrapper);
if(appOrderEntity==null) {
return Result.error("未找到对应数据");
}
@ -132,6 +145,32 @@ public class OrderController {
return Result.OK(url);
}
/**
* 生成合同
* @param orderId 订单 id
* @return
*/
@AutoLog(value = "合同订单表-取消合同")
@ApiOperation(value="合同订单表-取消合同", notes="合同订单表-取消合同")
@GetMapping(value = "/canelContract")
@ApiImplicitParams({
@ApiImplicitParam(name = "orderId", value = "订单id", required = true, dataType = "String", paramType = "query"),
})
public Result<String> canelContract(@RequestParam(value = "orderId")String orderId) {
// 获取当前用户信息只能生成当前账号订单
MLoginUser userInfo = userInfoUtil.getUserInfo();
QueryWrapper<AppOrder> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("create_by", userInfo.getNickName());
queryWrapper.eq("id",orderId);
queryWrapper.eq("status",1); // 未生效的订单才可以生成
AppOrder appOrderEntity = appOrderService.getOne(queryWrapper);
if(appOrderEntity==null) {
return Result.error("未找到对应数据");
}
orderService.canelOrderContract(appOrderEntity);
return Result.OK("取消成功");
}
/**
* 编辑
*


+ 7
- 12
jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/entity/OrderInfo.java View File

@ -1,5 +1,6 @@
package org.jeecg.modules.miniapp.order.entity;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.jeecg.common.aspect.annotation.Dict;
@ -60,8 +61,7 @@ public class OrderInfo implements Serializable {
/**营业执照*/
private java.lang.String busLicense;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private java.util.Date createTime;
/**订单状态*/
@Dict(dicCode = "order_status")
@ -71,8 +71,7 @@ public class OrderInfo implements Serializable {
/**收款方*/
private java.lang.String payee;
/**收款时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private java.util.Date payeeTime;
/**支付凭证*/
private java.lang.String payVoucherUrl;
@ -98,8 +97,7 @@ public class OrderInfo implements Serializable {
/**里程*/
private java.lang.String mileage;
/**购车时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private java.util.Date buyTime;
/**车辆购置价*/
private java.math.BigDecimal buyMoney;
@ -122,13 +120,11 @@ public class OrderInfo implements Serializable {
/**服务费*/
private java.math.BigDecimal serviceMoney;
/**生效时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JSONField(format = "yyyy-MM-dd")
private java.util.Date effectiveTime;
/**失效时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@JSONField(format = "yyyy-MM-dd")
private java.util.Date endTime;
/**服务年限*/
private java.lang.String serviceYear;
@ -150,8 +146,7 @@ public class OrderInfo implements Serializable {
private java.lang.String assigneeCardNo;
/**支付时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@JSONField(format = "yyyy-MM-dd")
private java.util.Date payTime;
/**经销商地址*/
private java.lang.String dealerAddress;


+ 7
- 0
jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/OrderService.java View File

@ -28,4 +28,11 @@ public interface OrderService {
* @return
*/
String addOrderContract(AppOrder appOrder);
/**
* 取消订单合同
* @param appOrder
* @return
*/
void canelOrderContract(AppOrder appOrder);
}

+ 55
- 8
jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/impl/OrderServiceImpl.java View File

@ -7,8 +7,10 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.vo.MLoginUser;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.modules.miniapp.order.entity.OrderInfo;
import org.jeecg.modules.miniapp.order.service.OrderService;
import org.jeecg.modules.miniapp.utils.PdfFormUtils;
import org.jeecg.modules.miniapp.utils.UserInfoUtil;
import org.jeecg.modules.sysMiniapp.order.entity.AppOrder;
import org.jeecg.modules.sysMiniapp.order.entity.AppOrderCar;
@ -20,15 +22,22 @@ import org.jeecg.modules.sysMiniapp.order.mapper.AppOrderMapper;
import org.jeecg.modules.sysMiniapp.order.mapper.AppOrderVoucherMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import static org.jeecg.modules.miniapp.utils.PdfFormUtils.*;
@ -50,6 +59,11 @@ public class OrderServiceImpl implements OrderService {
private AppOrderFinanceMapper appOrderFinanceMapper;
@Autowired
private UserInfoUtil userInfoUtil;
@Autowired
private PdfFormUtils pdfFormUtils;
@Value(value="${jeecg.uploadType}")
private String uploadType;
/**
@ -66,19 +80,20 @@ public class OrderServiceImpl implements OrderService {
MLoginUser user =userInfoUtil.getUserInfo();
// 生成唯一订单号
appOrder.setOrderNum(
MessageFormat.format("{0}{1}{3}",
MessageFormat.format("{0}{1}{2}",
"CXSC",
DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN),
String.valueOf(new Snowflake(1, 1).nextId()))
);
DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN),
String.valueOf(ThreadLocalRandom.current().nextInt(100000, 1000000))));
appOrder.setStatus(0); // 默认未生效
// 当前登录用户
appOrder.setCreateBy(user.getNickName());
appOrder.setCreateTime(new Date());
appOrderMapper.insert(appOrder);
if(appOrderCarList!=null && appOrderCarList.size()>0) {
for(AppOrderCar entity:appOrderCarList) {
//外键设置
entity.setOrderFkId(appOrder.getId());
entity.setCreateBy(user.getNickName());
appOrderCarMapper.insert(entity);
}
}
@ -86,6 +101,7 @@ public class OrderServiceImpl implements OrderService {
for(AppOrderVoucher entity:appOrderVoucherList) {
//外键设置
entity.setOrderFkId(appOrder.getId());
entity.setCreateBy(user.getNickName());
appOrderVoucherMapper.insert(entity);
}
}
@ -93,6 +109,7 @@ public class OrderServiceImpl implements OrderService {
for(AppOrderFinance entity:appOrderFinanceList) {
//外键设置
entity.setOrderFkId(appOrder.getId());
entity.setCreateBy(user.getNickName());
appOrderFinanceMapper.insert(entity);
}
}
@ -121,15 +138,24 @@ public class OrderServiceImpl implements OrderService {
String contractUrl = null;
// pdf 文件表单填充
// 1.定义输出临时路径
String outputPath = "/Users/tanzs/Downloads/" + appOrder.getOrderNum() +".pdf";
String outputPath = System.getProperty("java.io.tmpdir") + "/" + appOrder.getOrderNum() +".pdf";
// 2.转换实体类到 Map
try {
Map<String,String> formData = jsonToMap(JSONObject.toJSONString(orderInfo));
log.info("FormData: " + JSONObject.toJSONString(formData));
log.debug("FormData: " + JSONObject.toJSONString(formData));
//3. 拼接 pdf
fillPdfFormFromUrl(appOrder.getProductContractTemp(),outputPath,formData,6.5f);
pdfFormUtils.fillPdfFormFromUrl(appOrder.getProductContractTemp(),outputPath,formData,6.5f);
//4. 调用合同上传 oss
File pdfFile = new File(outputPath);
contractUrl = CommonUtils.upload(convertFileToMultipartFile(pdfFile), "contract", uploadType);
// 5. 更新订单表
appOrder.setStatus(1); // 更改订单状态
appOrder.setContractUrl(contractUrl);
appOrder.setUpdateBy(userInfoUtil.getUserInfo().getNickName());
appOrder.setUpdateTime(new Date());
appOrderMapper.updateById(appOrder);
// 删除临时文件
pdfFile.delete();
} catch (Exception e) {
log.error("合同生成失败,订单编号:{}",appOrder.getOrderNum());
throw new RuntimeException(e);
@ -137,6 +163,27 @@ public class OrderServiceImpl implements OrderService {
return contractUrl;
}
@Override
public void canelOrderContract(AppOrder appOrder) {
MLoginUser userInfo = userInfoUtil.getUserInfo();
appOrder.setUpdateBy(userInfo.getNickName());
appOrder.setStatus(0);
appOrderMapper.updateById(appOrder);
}
private MultipartFile convertFileToMultipartFile(File file) throws IOException {
FileInputStream inputStream = new FileInputStream(file);
return new MockMultipartFile(file.getName(), file.getName(), "application/octet-stream", inputStream);
}
// 订单号生成
public static void main(String[] args) {
System.err.println(MessageFormat.format("{0}{1}{2}",
"CXSC",
DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN),
String.valueOf(ThreadLocalRandom.current().nextInt(100000, 1000000))));
}
}

+ 0
- 1
jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/product/controller/MProductController.java View File

@ -53,7 +53,6 @@ public class MProductController {
@ApiOperation(value="产品管理-查询所有产品服务", notes="产品管理-查询所有产品服务")
@GetMapping(value = "/categories")
@IgnoreAuth
public Result<List<CategoryProductDTO>> query(@RequestParam(name = "name",required = false)String name) {
return mProductService.getAllCateGoryProduct(name);
}


+ 75
- 24
jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/utils/PdfFormUtils.java View File

@ -4,28 +4,54 @@ import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.io.font.FontProgram;
import com.itextpdf.io.font.FontProgramFactory;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.font.TrueTypeCollection;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import static com.itextpdf.kernel.pdf.PdfName.BaseFont;
/**
* @author Tanzs
* @date 2025/2/19 下午3:29
* @description PDF表单填充工具类
*/
@Component
@Slf4j
public class PdfFormUtils {
private static final Gson gson = new Gson();
// 本地使用调试字体路径
private static final String TEST_FONT_PATH = "/Users/tanzs/Documents/fonts/simsun.ttc,0";
// TODO 环境变量获取文字路径重新部署需要复制 resource 下的字体文件到指定路径
@Value(value = "${jeecg.path.fonts}")
private String DEFAULT_FONT_PATH;
/**
* 通过 pdf 文本域拼接 PDF 表单
@ -42,19 +68,26 @@ public class PdfFormUtils {
// 获取表单
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
// 填写表单字段
// 打印所有字段名称
Map<String, PdfFormField> fields = form.getAllFormFields();
for (String fieldName : fields.keySet()) {
System.out.println("Field name: " + fieldName);
}
// 创建字体
PdfFont baseFont = PdfFontFactory.createFont(TEST_FONT_PATH, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED);
// 填写表单字段
for (Map.Entry<String, String> entry : formData.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue();
// 确保字段存在并填写值
if (fields.containsKey(fieldName)) {
fields.get(fieldName).setValue(fieldValue);
fields.get(fieldName).setFontSize(fontSize); // 设置字体大小
PdfFormField field = fields.get(fieldName);
if (field != null && field.getFormType() == PdfName.Tx) { // 检查是否为文本字段
field.setValue(fieldValue);
field.setFont(baseFont);
field.setFontSize(fontSize);
} else {
System.out.println("Field not found or not a text field: " + fieldName);
}
}
@ -70,34 +103,39 @@ public class PdfFormUtils {
/**
* 通过 pdf 文本域拼接 PDF 表单
* @param templateUrl PDF 表单文件 URL例如 "https://example.com/template.pdf"
* @param outputPath 填充后的 PDF 文件路径
* @param outputFilePath 填充后的 PDF 文件路径
* @param formData 填充的数据键为表单字段名称值为填充的值
* @param fontSize 字体大小
*/
public static void fillPdfFormFromUrl(String templateUrl, String outputPath, Map<String, String> formData, float fontSize) {
public void fillPdfFormFromUrl(String templateUrl, String outputFilePath, Map<String, String> formData, float fontSize) {
try {
// URL 获取输入流
URL url = new URL(templateUrl);
try (InputStream templateInputStream = url.openStream();
PdfWriter writer = new PdfWriter(outputPath);
PdfWriter writer = new PdfWriter(outputFilePath);
PdfDocument pdfDoc = new PdfDocument(new PdfReader(templateInputStream), writer)) {
// 获取表单
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
// 填写表单字段
// 打印所有字段名称
Map<String, PdfFormField> fields = form.getAllFormFields();
for (String fieldName : fields.keySet()) {
System.out.println("Field name: " + fieldName);
log.debug("Field name: " + fieldName);
}
// 创建字体
PdfFont baseFont = PdfFontFactory.createFont(DEFAULT_FONT_PATH, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED);
// 填写表单字段
for (Map.Entry<String, String> entry : formData.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue();
// 确保字段存在并填写值
if (fields.containsKey(fieldName)) {
fields.get(fieldName).setValue(fieldValue);
fields.get(fieldName).setFontSize(fontSize); // 设置字体大小
PdfFormField field = fields.get(fieldName);
if (field != null && field.getFormType() == PdfName.Tx) { // 检查是否为文本字段
field.setValue(fieldValue);
field.setFont(baseFont);
field.setFontSize(fontSize);
}
}
@ -106,20 +144,28 @@ public class PdfFormUtils {
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("pdf合同生成失败,请稍后重试!");
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("pdf合同生成失败,请稍后重试!");
}
}
public static void fillPdfFormFromUrl2(String templateUrl, String outputPath, Map<String, String> formData, float fontSize) {
/**
* 通过 pdf 文本域拼接 PDF 表单
* @param templateUrl PDF 表单文件 URL例如 "https://example.com/template.pdf"
* @param outputFilePath 填充后的 PDF 文件路径
* @param formData 填充的数据键为表单字段名称值为填充的值
* @param fontSize 字体大小
*/
public static void fillPdfFormFromUrlLocal(String templateUrl, String outputFilePath, Map<String, String> formData, float fontSize) {
try {
// URL 获取输入流
URL url = new URL(templateUrl);
try (InputStream templateInputStream = url.openStream();
PdfWriter writer = new PdfWriter(outputPath);
PdfWriter writer = new PdfWriter(outputFilePath);
PdfDocument pdfDoc = new PdfDocument(new PdfReader(templateInputStream), writer)) {
// 获取表单
@ -130,6 +176,8 @@ public class PdfFormUtils {
for (String fieldName : fields.keySet()) {
System.out.println("Field name: " + fieldName);
}
// 创建字体
PdfFont baseFont = PdfFontFactory.createFont(TEST_FONT_PATH, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED);
// 填写表单字段
for (Map.Entry<String, String> entry : formData.entrySet()) {
@ -139,6 +187,7 @@ public class PdfFormUtils {
PdfFormField field = fields.get(fieldName);
if (field != null && field.getFormType() == PdfName.Tx) { // 检查是否为文本字段
field.setValue(fieldValue);
field.setFont(baseFont);
field.setFontSize(fontSize);
} else {
System.out.println("Field not found or not a text field: " + fieldName);
@ -158,6 +207,8 @@ public class PdfFormUtils {
}
/**
* 实体类转换成Map
* @param obj
@ -189,21 +240,21 @@ public class PdfFormUtils {
// 示例调用此工具类
public static void main(String[] args) {
String templatePath = "/Users/tanzs/Downloads/carT.pdf";
// String templateUrl = "https://jf.sh.189.cn/minio/gov-miniapp/order_pdf/carT.pdf";
// String templatePath = "/Users/tanzs/Downloads/carT.pdf";
String templateUrl = "https://img.augcl.com/temp/carT_1740226107035.pdf";
String outputPath = "/Users/tanzs/Downloads/carR.pdf";
float fontSize = 6.5f; // 设置字体大小
// 填写的数据
Map<String, String> formData = new HashMap<String, String>();
formData.put("cust_name", "张三");
formData.put("cust_phone", "123213");
formData.put("custName", "张三");
formData.put("custPhone", "123213");
formData.put("carNo", "京A12345");
formData.put("cust_address", "测试地址");
formData.put("custAddress", "测试地址");
// 调用工具类进行表单填写
fillPdfForm(templatePath, outputPath, formData, fontSize);
// fillPdfFormFromUrl(templateUrl, outputPath, formData, fontSize);
// fillPdfForm(templatePath, outputPath, formData, fontSize);
fillPdfFormFromUrlLocal(templateUrl, outputPath, formData, fontSize);
}
}

+ 1
- 1
jeecg-module-system/jeecg-system-start/pom.xml View File

@ -93,7 +93,7 @@
<!-- 输出目录为 lib 文件夹 -->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<!-- 只复制运行时依赖 -->
<scope>runtime</scope>
<!-- <scope>runtime</scope>-->
<!-- 不覆盖现有的文件 -->
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>


+ 2
- 0
jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml View File

@ -227,6 +227,8 @@ jeecg:
upload: /opt/upFiles
#webapp文件路径
webapp: /opt/webapp
# 字体路径
fonts: "/Users/tanzs/Documents/fonts/simsun.ttc,0"
shiro:
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/bigscreen/category/**,/bigscreen/visual/**,/bigscreen/map/**,/jmreport/bigscreen2/**
#阿里云oss存储和大鱼短信秘钥配置


+ 2
- 0
jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml View File

@ -227,6 +227,8 @@ jeecg:
upload: /opt/jeecg-boot/upload
#webapp文件路径
webapp: /opt/jeecg-boot/webapp
# 字体路径
fonts: "/opt/fonts/simsun.ttc,0"
shiro:
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/bigscreen/category/**,/bigscreen/visual/**,/bigscreen/map/**,/jmreport/bigscreen2/**,/api/getUserInfo
#阿里云oss存储和大鱼短信秘钥配置


+ 2
- 0
jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml View File

@ -227,6 +227,8 @@ jeecg:
upload: /opt/upFiles
#webapp文件路径
webapp: /opt/webapp
# 字体路径
fonts: "/opt/fonts/simsun.ttc,0"
shiro:
excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/bigscreen/category/**,/bigscreen/visual/**,/bigscreen/map/**,/jmreport/bigscreen2/**
#阿里云oss存储和大鱼短信秘钥配置


BIN
jeecg-module-system/jeecg-system-start/src/main/resources/fonts/STKAITI.TTF View File


BIN
jeecg-module-system/jeecg-system-start/src/main/resources/fonts/simsun.ttc View File


Loading…
Cancel
Save