diff --git a/doc/report.ftl b/doc/report.ftl index ca4aa36..d1ae676 100644 --- a/doc/report.ftl +++ b/doc/report.ftl @@ -31,21 +31,21 @@
- 合同编号:PS- - ${contract.contractCode} - 客户编号: - ${contract.customId} -
---> +<#-- 合同编号:PS- --> +<#-- ${contract.contractCode} --> +<#-- 客户编号: --> +<#-- ${contract.customId} --> +<#--
--> +<#--- ${company.companyName}
+ ${main.name}服务合同
本合同由缔约双方在自愿、平等、公平及诚实信用原则的基础上,本着共赢互利原则,根据《中华人民共和国民法典》等
@@ -69,8 +69,24 @@+ ${item.businessType}-金额:${item.businessAmount}元 + <#if item.businessDesc?? && item.businessDesc != ""> + -备注:${item.businessDesc} + #if> +
<#list item.detailBos as detail> -${detail.businessProjectLabel}——${detail.amount}
+${detail.businessProjectLabel} + <#if detail.extentInfo?? && detail.extentInfo != ""> + :${detail.extentInfo} + #if> + <#if detail.amount??> + -金额:${detail.amount} + #if> + <#if detail.amountDesc?? && detail.amountDesc != ""> + -备注:${detail.amountDesc} + #if> +
#list>公司名称:${company.companyName}
-账号:${company.companyAccountBank}
-开户行:${company.companyAccountBankAdress}
+公司名称:${main.name?if_exists}
+账号:${main.account?if_exists}
+开户行:${main.bank?if_exists}
<#if text2?? && text2 != ""> - ${contract.signDesc} + ${contract.signDesc?if_exists} <#else> 无 #if> @@ -132,7 +148,11 @@
一、服务期限
-本合同中的服务周期为 至 。
+ <#if contract.startServiceDate??> +本合同中的服务周期为 + ${contract.startServiceDate?string('yyyy年MM月dd日')}至${contract.endServiceDate?string('yyyy年MM月dd日')}。 +
+ #if>本合同中的企业托管服务,在合同到期前 30 天,乙方有义务告知甲方。如果双方在合同期满前 30 天内未提出终止或变更要
求,未办理交接手续,本合同将自行延期一年。如为其他业务,则与双方约定时间为准。
@@ -196,9 +216,9 @@裁决是终局性的,对双方具有约束力。因争议解决产生的案件受理费、律师费、保全费、公证费、鉴定费等由败诉方承担。
(五)本合同传真及扫描件与合同原件具有同等法律效力。
-
甲方名称(签章): ${customer.customName}
-甲方联系人: ${customer.customName}
-联系方式: ${customer.customMobile}
+甲方名称(签章): ${company.companyName?if_exists}
+甲方联系人: ${company.legalPersonName?if_exists}
+联系方式: ${company.legalPersonPhone?if_exists}
签约日期: ${contract.applyDate?string('yyyy年MM月dd日')} <#-- 年 月 @@ -206,9 +226,9 @@
-
乙方名称(签章): ${customer.customName}
-乙方联系人: ${customer.customName}
-联系方式: ${customer.customName}
+乙方名称(签章): ${main.name?if_exists}
+乙方联系人: ${user.nickname?if_exists}
+联系方式: ${user.phonenumber?if_exists}
签约日期: ${contract.applyDate?string('yyyy年MM月dd日')}
<#-- 年
月
diff --git a/pusong-admin/src/main/java/com/pusong/web/service/SysLoginService.java b/pusong-admin/src/main/java/com/pusong/web/service/SysLoginService.java
index ceeeb94..efa9e18 100644
--- a/pusong-admin/src/main/java/com/pusong/web/service/SysLoginService.java
+++ b/pusong-admin/src/main/java/com/pusong/web/service/SysLoginService.java
@@ -156,6 +156,7 @@ public class SysLoginService {
loginUser.setUsername(user.getUserName());
loginUser.setNickname(user.getNickName());
loginUser.setUserType(user.getUserType());
+ loginUser.setPhonenumber(user.getPhonenumber());
loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId()));
loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId()));
TenantHelper.dynamic(user.getTenantId(), () -> {
diff --git a/pusong-common/pusong-common-core/src/main/java/com/pusong/common/core/domain/model/LoginUser.java b/pusong-common/pusong-common-core/src/main/java/com/pusong/common/core/domain/model/LoginUser.java
index d9a98fe..cfd6c38 100644
--- a/pusong-common/pusong-common-core/src/main/java/com/pusong/common/core/domain/model/LoginUser.java
+++ b/pusong-common/pusong-common-core/src/main/java/com/pusong/common/core/domain/model/LoginUser.java
@@ -106,6 +106,12 @@ public class LoginUser implements Serializable {
*/
private String nickname;
+
+ /**
+ * 手机号
+ */
+ private String phonenumber;
+
/**
* 角色对象
*/
diff --git a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/NumBerTool.java b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/NumBerTool.java
new file mode 100644
index 0000000..ee834bd
--- /dev/null
+++ b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/NumBerTool.java
@@ -0,0 +1,118 @@
+package com.pusong.common.doc.util;
+
+public class NumBerTool {
+ private static final String[] NUMBERS = { "零", "壹", "贰", "叁", "肆", "伍", "陆",
+ "柒", "捌", "玖" };
+ /** 整数部分的单位 */
+ private static final String[] IUNIT = { "元", "拾", "佰", "仟", "万", "拾", "佰",
+ "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟" };
+ /** 小数部分的单位 */
+ private static final String[] DUNIT = { "角", "分"};
+
+
+ /**
+ * 得到大写金额。
+ */
+ public static String digitUppercase(String str) {
+ str = str.replaceAll(",", "");// 去掉","
+ String integerStr;// 整数部分数字
+ String decimalStr;// 小数部分数字
+ // 初始化:分离整数部分和小数部分
+ if (str.indexOf(".") > 0) {
+ integerStr = str.substring(0, str.indexOf("."));
+ decimalStr = str.substring(str.indexOf(".") + 1);
+ } else if (str.indexOf(".") == 0) {
+ integerStr = "";
+ decimalStr = str.substring(1);
+ } else {
+ integerStr = str;
+ decimalStr = "";
+ }
+ // integerStr去掉首0,不必去掉decimalStr的尾0(超出部分舍去)
+ if (!integerStr.equals("")) {
+ integerStr = Long.toString(Long.parseLong(integerStr));
+ if (integerStr.equals("0")) {
+ integerStr = "";
+ }
+ }
+ // overflow超出处理能力,直接返回
+ if (integerStr.length() > IUNIT.length) {
+ System.out.println(str + ":超出处理能力");
+ return str;
+ }
+ int[] integers = toArray(integerStr);// 整数部分数字
+ boolean isMust5 = isMust5(integerStr);// 设置万单位
+ int[] decimals = toArray(decimalStr);// 小数部分数字
+ return getChineseInteger(integers, isMust5) + getChineseDecimal(decimals);
+ }
+ /**
+ * 整数部分和小数部分转换为数组,从高位至低位
+ */
+ private static int[] toArray(String number) {
+ int[] array = new int[number.length()];
+ for (int i = 0; i < number.length(); i++) {
+ array[i] = Integer.parseInt(number.substring(i, i + 1));
+ }
+ return array;
+ }
+ /**
+ * 得到中文金额的整数部分。
+ */
+ private static String getChineseInteger(int[] integers, boolean isMust5) {
+ StringBuffer chineseInteger = new StringBuffer("");
+ int length = integers.length;
+ for (int i = 0; i < length; i++) {
+ // 0出现在关键位置:1234(万)5678(亿)9012(万)3456(元)
+ // 特殊情况:10(拾元、壹拾元、壹拾万元、拾万元)
+ String key = "";
+ if (integers[i] == 0) {
+ if ((length-i) == 13)// 万(亿)(必填)
+ key = IUNIT[4];
+ else if ((length-i) == 9)// 亿(必填)
+ key = IUNIT[8];
+ else if ((length-i) == 5 && isMust5)// 万(不必填)
+ key = IUNIT[4];
+ else if ((length-i) == 1)// 元(必填)
+ key = IUNIT[0];
+ // 0遇非0时补零,不包含最后一位
+ if ((length-i) > 1 && integers[i + 1] != 0)
+ key += NUMBERS[0];
+ }
+ chineseInteger.append(integers[i] == 0 ? key
+ : (NUMBERS[integers[i]] + IUNIT[length - i - 1]));
+ }
+ return chineseInteger.toString();
+ }
+ /**
+ * 得到中文金额的小数部分。
+ */
+ private static String getChineseDecimal(int[] decimals) {
+ StringBuffer chineseDecimal = new StringBuffer("");
+ for (int i = 0; i < decimals.length; i++) {
+ // 舍去2位小数之后的
+ if (i == 2)
+ break;
+ chineseDecimal.append(decimals[i] == 0 ? ""
+ : (NUMBERS[decimals[i]] + DUNIT[i]));
+ }
+ return chineseDecimal.toString();
+ }
+ /**
+ * 判断第5位数字的单位"万"是否应加。
+ */
+ private static boolean isMust5(String integerStr) {
+ int length = integerStr.length();
+ if (length > 4) {
+ String subInteger = "";
+ if (length > 8) {
+ // 取得从低位数,第5到第8位的字串
+ subInteger = integerStr.substring(length-8, length-4);
+ } else {
+ subInteger = integerStr.substring(0, length-4);
+ }
+ return Integer.parseInt(subInteger) > 0;
+ } else {
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PDFBuilder.java b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PDFBuilder.java
index 8fddb45..a95f599 100644
--- a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PDFBuilder.java
+++ b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PDFBuilder.java
@@ -3,15 +3,9 @@ package com.pusong.common.doc.util;
import java.io.IOException;
-import com.itextpdf.text.Document;
-import com.itextpdf.text.DocumentException;
-import com.itextpdf.text.Element;
-import com.itextpdf.text.Font;
-import com.itextpdf.text.Image;
-import com.itextpdf.text.PageSize;
-import com.itextpdf.text.Phrase;
-import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
+import com.pusong.common.core.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,59 +20,47 @@ public class PDFBuilder extends PdfPageEventHelper {
/**
* 页眉
*/
- public String header = "";
-
+ public String header ;
/**
- * 文档字体大小,页脚页眉最好和文本大小一致
+ * 是否签章
*/
- public int presentFontSize = 10;
-
+ public Boolean isSign ;
/**
- * 文档页面大小,最好前面传入,否则默认为A4纸张
+ * 是否签章
*/
- public Rectangle pageSize = PageSize.A4;
-
- // 模板
- public PdfTemplate total;
-
- // 基础字体对象
- public BaseFont bf = null;
-
+ public String imagepath ;
// 利用基础字体生成的字体对象,一般用于生成中文文字
- public Font fontDetail = null;
+ public static Font fontDetail = null;
+ // 基础字体对象
+ private static BaseFont baseFont;
+ // 生成下划线空白占位符
+ private static String Blank;
+ static {
+ try {
+ // 中文字体依赖itext得itext-asian包
+ baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 212; i++) {
+ sb.append("\u00a0");
+ }
+ Blank = sb.toString();
+ fontDetail = new Font(baseFont);
+ } catch (DocumentException e) {
+ log.error("初始化字体失败", e);
+ } catch (IOException e) {
+ log.error("初始化字体失败", e);
+ }
+ }
/**
*
* Creates a new instance of PdfReportM1HeaderFooter 无参构造方法.
*
*/
- public PDFBuilder() {
-
- }
-
- /**
- *
- * Creates a new instance of PdfReportM1HeaderFooter 构造方法.
- *
- * @param yeMei
- * 页眉字符串
- * @param presentFontSize
- * 数据体字体大小
- * @param pageSize
- * 页面文档大小,A4,A5,A6横转翻转等Rectangle对象
- */
- public PDFBuilder(String yeMei, int presentFontSize, Rectangle pageSize) {
- this.header = yeMei;
- this.presentFontSize = presentFontSize;
- this.pageSize = pageSize;
- }
-
- public void setHeader(String header) {
- this.header = header;
- }
-
- public void setPresentFontSize(int presentFontSize) {
- this.presentFontSize = presentFontSize;
+ public PDFBuilder(Object header,Object isSign,String imagepath) {
+ this.header = header == null?null:header.toString();
+ this.isSign = isSign == null?null:(Boolean)isSign;
+ this.imagepath = imagepath;
}
/**
@@ -88,9 +70,15 @@ public class PDFBuilder extends PdfPageEventHelper {
* @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf.text.pdf.PdfWriter,
* com.itextpdf.text.Document)
*/
- /* public void onOpenDocument(PdfWriter writer, Document document) {
- total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高
- }*/
+ public void onOpenDocument(PdfWriter writer, Document document) {
+ }
+
+ @Override
+
+ public void onStartPage(PdfWriter writer, Document document) {
+ super.onStartPage(writer, document);
+
+ }
/**
*
@@ -100,85 +88,44 @@ public class PDFBuilder extends PdfPageEventHelper {
* com.itextpdf.text.Document)
*/
public void onEndPage(PdfWriter writer, Document document) {
-// this.addPage(writer, document);
- this.addWatermark(writer);
+ //是否添加页眉
+ if(StringUtils.isNotBlank(header)){
+ this.addPage(writer, document);
+ }
+ //是否签章
+ if(isSign){
+ this.addSign(writer);
+ }
+
}
//加分页
- public void addPage(PdfWriter writer, Document document){
- try {
- if (bf == null) {
- bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
- }
- if (fontDetail == null) {
- fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体
- }
- } catch (DocumentException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+ public void addPage(PdfWriter writer, Document document) {
+ //页眉没有数据的话直接return
+ if(StringUtils.isBlank(header)){
+ return;
}
-
+ //生成下划线,使用空格占位
+ ColumnText.showTextAligned(writer.getDirectContent(),
+ Element.ALIGN_LEFT, new Phrase(PDFBuilder.Blank, new Font(PDFBuilder.baseFont, Font.DEFAULTSIZE, Font.UNDERLINE)),
+ document.left(-1), document.top()+10, 0);
// 1.写入页眉
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_LEFT, new Phrase(header, fontDetail),
- document.right()/2, document.top() - 17, 0);
-
-
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < 210; i++) {
- sb.append("\u00a0");
- }
-
- ColumnText.showTextAligned(writer.getDirectContent(),
- Element.ALIGN_LEFT, new Phrase(sb.toString(), fontDetail),
- document.left(-1), document.top() -50, 0);
-
-// // 2.写入前半部分的 第 X页/共
-// int pageS = writer.getPageNumber();
-// String foot1 = "第 " + pageS + " 页 /共";
-// Phrase footer = new Phrase(foot1, fontDetail);
-//
-// // 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len
-// float len = bf.getWidthPoint(foot1, presentFontSize);
-//
-// // 4.拿到当前的PdfContentByte
-// PdfContentByte cb = writer.getDirectContent();
-//
-// // 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F
-// // 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了
-// // ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。
-// ColumnText
-// .showTextAligned(
-// cb,
-// Element.ALIGN_CENTER,
-// footer,
-// (document.rightMargin() + document.right()
-// + document.leftMargin() - document.left() - len) / 2.0F + 20F,
-// document.bottom() - 20, 0);
-//
-// // 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F +
-// // len , y 轴和之前的保持一致,底边界-20
-// cb.addTemplate(total, (document.rightMargin() + document.right()
-// + document.leftMargin() - document.left()) / 2.0F + 20F,
-// document.bottom() - 20); // 调节模版显示的位置
-
+ document.right()/2+20, document.top()+10 , 0);
}
- public static void main(String[] args) {
- System.out.println(System.getProperty("user.dir"));
- }
- //加水印
- public void addWatermark(PdfWriter writer){
+ //加半章图片
+ public void addSign(PdfWriter writer){
String psth;
- if(writer.getPageNumber() == 1){
- psth = System.getProperty("user.dir")+"\\doc\\image\\leftZ.png";
- }else if (writer.getPageNumber() == 2){
- psth = System.getProperty("user.dir")+"\\doc\\image\\rightZ.png";
- }else{
+ if(writer.getPageNumber()%2 == 1){
+ psth = imagepath+"\\doc\\image\\leftZ.png";
+ }else/* if (writer.getPageNumber() == 2)*/{
+ psth = imagepath+"\\doc\\image\\rightZ.png";
+ }/*else{
return;
- }
- // 水印图片
+ }*/
+ // 加半章图片
Image image;
try {
image = Image.getInstance(psth);
@@ -187,17 +134,9 @@ public class PDFBuilder extends PdfPageEventHelper {
content.beginText();
image.setAbsolutePosition(450+75,400);
content.addImage(image);
-// // 开始写入水印
-// for(int k=0;k<5;k++){
-// for (int j = 0; j <4; j++) {
-// image.setAbsolutePosition(150*j,170*k);
-// content.addImage(image);
-// }
-// }
content.endText();
} catch (IOException | DocumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ log.error("加半章图片异常",e);
}
}
diff --git a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PdfGenerator.java b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PdfGenerator.java
index 066dbae..63da866 100644
--- a/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PdfGenerator.java
+++ b/pusong-common/pusong-common-doc/src/main/java/com/pusong/common/doc/util/PdfGenerator.java
@@ -2,6 +2,7 @@ package com.pusong.common.doc.util;
import com.alibaba.fastjson.JSON;
import com.itextpdf.text.Document;
+import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Configuration;
@@ -20,7 +21,10 @@ import java.util.Map;
public class PdfGenerator {
private static final Logger log = LoggerFactory.getLogger(PdfGenerator.class);
-
+ //标题
+ public static final String HEAD = "head";
+ //是否签章
+ public static final String SIGN = "isSign";
public static void main(String[] args) throws Exception {
@@ -48,8 +52,11 @@ public class PdfGenerator {
// String html = processTemplate(template, data);
// // 生成PDF
// generatePdf(html, "D:/王立帅/临时/output.pdf");
- String str = " - {\"business\":[{\"businessAmount\":500,\"businessType\":\"1\",\"contractCode\":\"\",\"detailBos\":[{\"amount\":100,\"amountDesc\":\"备注\",\"businessProject\":\"1\",\"businessProjectLabel\":\"测试1\",\"contractCode\":\"\",\"id\":0}],\"id\":0}],\"contract\":{\"applyDate\":1722355200000,\"companyId\":0,\"contractAmount\":500,\"contractCode\":\"\",\"contractMain\":\"1\",\"contractName\":\"合同名称\",\"customId\":1816388144534081538,\"customManager\":1,\"customScene\":\"\",\"isProxy\":\"\",\"params\":{},\"payModeDesc\":\"支付方式\",\"signDesc\":\"描述描述\"},\"company\":{\"companyAccountBank\":\"银行编码\",\"companyAccountBankAdress\":\"开户行地址\",\"companyAdress\":\"公司地址\",\"companyName\":\"公司名\",\"customId\":0,\"id\":0,\"legalPersonIdcard\":\"法人身份证\",\"legalPersonName\":\"法人姓名\",\"legalPersonPhone\":\"法人手机号\"},\"customer\":{\"black\":\"0\",\"createBy\":1,\"createDept\":103,\"createTime\":1721895655000,\"customLevel\":\"2\",\"customManager\":3,\"customMobile\":\"13511245332\",\"customName\":\"东洲\",\"customSource\":\"抖音\",\"customStatus\":\"1\",\"delFlag\":0,\"id\":1816388144534081538,\"params\":{},\"tenantId\":\"000000\",\"updateBy\":1,\"updateTime\":1723097358000}}";
- makePdf(JSON.parseObject(str,Map.class),"D:/王立帅/临时/output.pdf","report.ftl");
+ String str = "{\"business\":[{\"businessAmount\":500,\"businessType\":\"1\",\"contractCode\":\"\",\"detailBos\":[{\"amount\":100,\"amountDesc\":\"备注\",\"businessProject\":\"1\",\"businessProjectLabel\":\"测试1\",\"contractCode\":\"\",\"id\":0}],\"id\":0}],\"contract\":{\"applyDate\":1722355200000,\"companyId\":0,\"contractAmount\":500,\"contractCode\":\"\",\"contractMain\":\"1\",\"contractName\":\"合同名称\",\"customId\":1816388144534081538,\"customManager\":1,\"customScene\":\"\",\"isProxy\":\"\",\"params\":{},\"payModeDesc\":\"支付方式\",\"signDesc\":\"描述描述\"},\"company\":{\"companyAccountBank\":\"银行编码\",\"companyAccountBankAdress\":\"开户行地址\",\"companyAdress\":\"公司地址\",\"companyName\":\"公司名\",\"customId\":0,\"id\":0,\"legalPersonIdcard\":\"法人身份证\",\"legalPersonName\":\"法人姓名\",\"legalPersonPhone\":\"法人手机号\"},\"customer\":{\"black\":\"0\",\"createBy\":1,\"createDept\":103,\"createTime\":1721895655000,\"customLevel\":\"2\",\"customManager\":3,\"customMobile\":\"13511245332\",\"customName\":\"东洲\",\"customSource\":\"抖音\",\"customStatus\":\"1\",\"delFlag\":0,\"id\":1816388144534081538,\"params\":{},\"tenantId\":\"000000\",\"updateBy\":1,\"updateTime\":1723097358000}}";
+ Map map = JSON.parseObject(str, Map.class);
+ map.put(HEAD,"sss");
+ map.put(SIGN,true);
+ makePdf(map,"D:/王立帅/临时/output.pdf","report.ftl");
}
@@ -64,8 +71,9 @@ public class PdfGenerator {
// 生成HTML
String html = processTemplate(template, data);
// 生成PDF
-// generatePdf(html, "D:/王立帅/临时/output.pdf");
- generatePdf(html, pdfpath);
+ PDFBuilder builder = new PDFBuilder(data.get(HEAD),data.get(SIGN),System.getProperty("user.dir"));
+ generatePdf(html, pdfpath, builder);
+
}
private static String processTemplate(Template template, Map