diff --git a/jeecg-module-miniapp/pom.xml b/jeecg-module-miniapp/pom.xml
index 26bb0cb..1844f4a 100644
--- a/jeecg-module-miniapp/pom.xml
+++ b/jeecg-module-miniapp/pom.xml
@@ -38,15 +38,13 @@
com.itextpdf
- itext-core
+ itext7-core
8.0.3
pom
-
- com.itextpdf
- forms
- 8.0.3
+ org.springframework
+ spring-test
diff --git a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/dict/controller/DictController.java b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/dict/controller/DictController.java
new file mode 100644
index 0000000..243db1b
--- /dev/null
+++ b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/dict/controller/DictController.java
@@ -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 queryDictItemsByCode(@RequestParam("code") String code){
+ return commonApi.queryDictItemsByCode(code);
+ }
+}
diff --git a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/controller/OrderController.java b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/controller/OrderController.java
index 262de33..13c926c 100644
--- a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/controller/OrderController.java
+++ b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/controller/OrderController.java
@@ -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 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 queryWrapper = QueryGenerator.initQueryWrapper(appOrder, req.getParameterMap(),customeRuleMap);
+ queryWrapper.eq("create_by",userInfo.getNickName());
Page page = new Page(pageNo, pageSize);
IPage 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 addContract(@RequestParam(value = "orderId")String orderId) {
- AppOrder appOrderEntity = appOrderService.getById(orderId);
+ // 获取当前用户信息,只能生成当前账号订单
+ MLoginUser userInfo = userInfoUtil.getUserInfo();
+ QueryWrapper 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 canelContract(@RequestParam(value = "orderId")String orderId) {
+ // 获取当前用户信息,只能生成当前账号订单
+ MLoginUser userInfo = userInfoUtil.getUserInfo();
+ QueryWrapper 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("取消成功");
+ }
+
/**
* 编辑
*
diff --git a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/entity/OrderInfo.java b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/entity/OrderInfo.java
index b5bef27..b72251d 100644
--- a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/entity/OrderInfo.java
+++ b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/entity/OrderInfo.java
@@ -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;
diff --git a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/OrderService.java b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/OrderService.java
index 5c0916a..d18794a 100644
--- a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/OrderService.java
+++ b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/OrderService.java
@@ -28,4 +28,11 @@ public interface OrderService {
* @return
*/
String addOrderContract(AppOrder appOrder);
+
+ /**
+ * 取消订单合同
+ * @param appOrder
+ * @return
+ */
+ void canelOrderContract(AppOrder appOrder);
}
diff --git a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/impl/OrderServiceImpl.java b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/impl/OrderServiceImpl.java
index fdd19c9..59b30af 100644
--- a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/impl/OrderServiceImpl.java
+++ b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/order/service/impl/OrderServiceImpl.java
@@ -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 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))));
+ }
+
}
diff --git a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/product/controller/MProductController.java b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/product/controller/MProductController.java
index fde880a..b820edb 100644
--- a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/product/controller/MProductController.java
+++ b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/product/controller/MProductController.java
@@ -53,7 +53,6 @@ public class MProductController {
@ApiOperation(value="产品管理-查询所有产品服务", notes="产品管理-查询所有产品服务")
@GetMapping(value = "/categories")
- @IgnoreAuth
public Result> query(@RequestParam(name = "name",required = false)String name) {
return mProductService.getAllCateGoryProduct(name);
}
diff --git a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/utils/PdfFormUtils.java b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/utils/PdfFormUtils.java
index df79c83..a57ac1d 100644
--- a/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/utils/PdfFormUtils.java
+++ b/jeecg-module-miniapp/src/main/java/org/jeecg/modules/miniapp/utils/PdfFormUtils.java
@@ -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 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 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 formData, float fontSize) {
+ public void fillPdfFormFromUrl(String templateUrl, String outputFilePath, Map 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 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 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 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 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 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 formData = new HashMap();
- 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);
}
}
diff --git a/jeecg-module-system/jeecg-system-start/pom.xml b/jeecg-module-system/jeecg-system-start/pom.xml
index 744e9d6..ce33b9f 100644
--- a/jeecg-module-system/jeecg-system-start/pom.xml
+++ b/jeecg-module-system/jeecg-system-start/pom.xml
@@ -93,7 +93,7 @@
${project.build.directory}/lib
- runtime
+
false
false
diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml b/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml
index fe77909..025a586 100644
--- a/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml
+++ b/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml
@@ -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存储和大鱼短信秘钥配置
diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml b/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml
index 104c7aa..f2876f5 100644
--- a/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml
+++ b/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml
@@ -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存储和大鱼短信秘钥配置
diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml b/jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml
index 39833aa..cd31d6a 100644
--- a/jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml
+++ b/jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml
@@ -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存储和大鱼短信秘钥配置
diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/fonts/STKAITI.TTF b/jeecg-module-system/jeecg-system-start/src/main/resources/fonts/STKAITI.TTF
new file mode 100644
index 0000000..5044116
Binary files /dev/null and b/jeecg-module-system/jeecg-system-start/src/main/resources/fonts/STKAITI.TTF differ
diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/fonts/simsun.ttc b/jeecg-module-system/jeecg-system-start/src/main/resources/fonts/simsun.ttc
new file mode 100644
index 0000000..40e9693
Binary files /dev/null and b/jeecg-module-system/jeecg-system-start/src/main/resources/fonts/simsun.ttc differ