生成合同的pdf
This commit is contained in:
parent
db3d02be1e
commit
a591fe024b
@ -31,21 +31,21 @@
|
||||
</style>
|
||||
<body>
|
||||
<div style="width: 100%;">
|
||||
<div style="width: 100% ;height: 5pt; "></div>
|
||||
<div >
|
||||
<p style="text-align:center;margin-left:300px;margin-top:1pt; margin-bottom:0pt;">
|
||||
<span style="">合同编号:PS- </span>
|
||||
<span style=" text-decoration:underline">${contract.contractCode} </span>
|
||||
<span style=""> 客户编号: </span>
|
||||
<span style=" text-decoration:underline">${contract.customId}
|
||||
</span></p>
|
||||
</div>
|
||||
<div style="width: 100% ;height: 3pt; "></div>
|
||||
<div style="width: 100% ;height: 0.75pt; background-color: black"></div>
|
||||
<#-- <div style="width: 100% ;height: 5pt; "></div>-->
|
||||
<#-- <div >-->
|
||||
<#-- <p style="text-align:center;margin-left:300px;margin-top:1pt; margin-bottom:0pt;">-->
|
||||
<#-- <span style="">合同编号:PS- </span>-->
|
||||
<#-- <span style=" text-decoration:underline">${contract.contractCode} </span>-->
|
||||
<#-- <span style=""> 客户编号: </span>-->
|
||||
<#-- <span style=" text-decoration:underline">${contract.customId} -->
|
||||
<#-- </span></p>-->
|
||||
<#-- </div>-->
|
||||
<#-- <div style="width: 100% ;height: 3pt; "></div>-->
|
||||
<#-- <div style="width: 100% ;height: 0.75pt; background-color: black"></div>-->
|
||||
|
||||
<#--<div style="width: 100% ;height: 17pt; "></div>-->
|
||||
<p style=" text-align:center; margin: 0 auto; font-size:14pt">
|
||||
<span style=" font-weight: bold">${company.companyName}</span></p>
|
||||
<span style=" font-weight: bold">${main.name}</span></p>
|
||||
<p style=" margin: 0 auto; text-align:center; font-size:16pt">
|
||||
<span style=" font-weight:bold">服务合同</span></p>
|
||||
<p class="content" style="margin-left:21pt; text-indent:19pt;">本合同由缔约双方在自愿、平等、公平及诚实信用原则的基础上,本着共赢互利原则,根据《中华人民共和国民法典》等</p>
|
||||
@ -69,8 +69,24 @@
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<div style="height: 5pt;width: 1pt"></div>
|
||||
<p class="content" style="text-indent:5pt">
|
||||
${item.businessType}-金额:${item.businessAmount}元
|
||||
<#if item.businessDesc?? && item.businessDesc != "">
|
||||
-备注:${item.businessDesc}
|
||||
</#if>
|
||||
</p>
|
||||
<#list item.detailBos as detail>
|
||||
<p class="content" style="text-indent:5pt">${detail.businessProjectLabel}——${detail.amount}</p>
|
||||
<p class="content" style="text-indent:32pt">${detail.businessProjectLabel}
|
||||
<#if detail.extentInfo?? && detail.extentInfo != "">
|
||||
:${detail.extentInfo}
|
||||
</#if>
|
||||
<#if detail.amount??>
|
||||
-金额:${detail.amount}
|
||||
</#if>
|
||||
<#if detail.amountDesc?? && detail.amountDesc != "">
|
||||
-备注:${detail.amountDesc}
|
||||
</#if>
|
||||
</p>
|
||||
</#list>
|
||||
</td>
|
||||
</tr>
|
||||
@ -82,9 +98,9 @@
|
||||
<td colspan="2" >
|
||||
<div style="height: 5pt;width: 1pt"></div>
|
||||
<div style="float: left;">
|
||||
<p class="content" style="text-indent:5pt">公司名称:${company.companyName}</p>
|
||||
<p class="content" style="text-indent:5pt">账号:${company.companyAccountBank}</p>
|
||||
<p class="content" style="text-indent:5pt">开户行:${company.companyAccountBankAdress}</p>
|
||||
<p class="content" style="text-indent:5pt">公司名称:${main.name?if_exists}</p>
|
||||
<p class="content" style="text-indent:5pt">账号:${main.account?if_exists}</p>
|
||||
<p class="content" style="text-indent:5pt">开户行:${main.bank?if_exists}</p>
|
||||
</div>
|
||||
<div style="float: left;">
|
||||
<img style=" width:50pt; height:50pt; " src="${imagePath}/doc/image/pay.png"/>
|
||||
@ -98,7 +114,7 @@
|
||||
<span style="">合同金额:共计¥</span>
|
||||
<span style=" text-decoration:underline"> ${contract.contractAmount}</span>
|
||||
<span style="">元(大写金额:</span>
|
||||
<span style=" text-decoration:underline"> </span>
|
||||
<span style=" text-decoration:underline">${contractAmount} </span>
|
||||
<span style="">元整),垫付项目中涉及银行开户、刻章等,实际价格以第三方机构及政府规定为准。除此之外,甲方无需向乙方支付其他任何费用。</span></p>
|
||||
</td>
|
||||
</tr>
|
||||
@ -119,7 +135,7 @@
|
||||
<div style="height: 5pt;width: 1pt"></div>
|
||||
<p class="content" style="text-indent:5pt">
|
||||
<#if text2?? && text2 != "">
|
||||
${contract.signDesc}
|
||||
${contract.signDesc?if_exists}
|
||||
<#else>
|
||||
无
|
||||
</#if>
|
||||
@ -132,7 +148,11 @@
|
||||
<p style=" text-indent:9pt; text-align:justify; ">
|
||||
<span style=""> </span></p>
|
||||
<p class="title">一、服务期限</p>
|
||||
<p class="content">本合同中的服务周期为 至 。</p>
|
||||
<#if contract.startServiceDate??>
|
||||
<p class="content">本合同中的服务周期为
|
||||
${contract.startServiceDate?string('yyyy年MM月dd日')}至${contract.endServiceDate?string('yyyy年MM月dd日')}。
|
||||
</p>
|
||||
</#if>
|
||||
<p class="content">本合同中的企业托管服务,在合同到期前 30 天,乙方有义务告知甲方。如果双方在合同期满前 30 天内未提出终止或变更要</p>
|
||||
<p class="content" style="text-indent:0pt;">求,未办理交接手续,本合同将自行延期一年。如为其他业务,则与双方约定时间为准。</p>
|
||||
|
||||
@ -196,9 +216,9 @@
|
||||
<p class="content" style="text-indent:0pt;">裁决是终局性的,对双方具有约束力。因争议解决产生的案件受理费、律师费、保全费、公证费、鉴定费等由败诉方承担。</p>
|
||||
<p class="content">(五)本合同传真及扫描件与合同原件具有同等法律效力。</p>
|
||||
<p class="content"> </p>
|
||||
<p class="content">甲方名称(签章): ${customer.customName}</p>
|
||||
<p class="content">甲方联系人: ${customer.customName}</p>
|
||||
<p class="content">联系方式: ${customer.customMobile}</p>
|
||||
<p class="content">甲方名称(签章): ${company.companyName?if_exists}</p>
|
||||
<p class="content">甲方联系人: ${company.legalPersonName?if_exists}</p>
|
||||
<p class="content">联系方式: ${company.legalPersonPhone?if_exists}</p>
|
||||
<p class="content">签约日期: ${contract.applyDate?string('yyyy年MM月dd日')}
|
||||
<#--<span style=" text-decoration:underline"></span> 年
|
||||
<span style=" text-decoration:underline"></span> 月
|
||||
@ -206,9 +226,9 @@
|
||||
</p>
|
||||
<p class="content"> </p>
|
||||
|
||||
<p class="content">乙方名称(签章): ${customer.customName}</p>
|
||||
<p class="content">乙方联系人: ${customer.customName}</p>
|
||||
<p class="content">联系方式: ${customer.customName}</p>
|
||||
<p class="content">乙方名称(签章): ${main.name?if_exists}</p>
|
||||
<p class="content">乙方联系人: ${user.nickname?if_exists}</p>
|
||||
<p class="content">联系方式: ${user.phonenumber?if_exists}</p>
|
||||
<p class="content">签约日期: ${contract.applyDate?string('yyyy年MM月dd日')}
|
||||
<#--<span style=" text-decoration:underline"> </span> 年
|
||||
<span style=" text-decoration:underline"> </span> 月
|
||||
|
@ -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(), () -> {
|
||||
|
@ -106,6 +106,12 @@ public class LoginUser implements Serializable {
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String phonenumber;
|
||||
|
||||
/**
|
||||
* 角色对象
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<String, Object> data) throws IOException, TemplateException {
|
||||
StringWriter writer = new StringWriter();
|
||||
@ -73,13 +81,13 @@ public class PdfGenerator {
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
private static void generatePdf(String html, String outputPath) {
|
||||
private static void generatePdf(String html, String outputPath,PDFBuilder builder) {
|
||||
Document document = null;
|
||||
PdfWriter writer = null;
|
||||
try{
|
||||
document = new Document();
|
||||
document = new Document(PageSize.A4, 36, 36, 50, 50);
|
||||
writer = PdfWriter.getInstance(document, new FileOutputStream(outputPath));
|
||||
PDFBuilder builder = new PDFBuilder();
|
||||
|
||||
writer.setPageEvent(builder);
|
||||
document.open();
|
||||
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(html.getBytes()),
|
||||
|
@ -12,17 +12,22 @@ import com.pusong.business.service.*;
|
||||
import com.pusong.business.service.approver.ApproverContainer;
|
||||
import com.pusong.business.service.approver.ApproverService;
|
||||
import com.pusong.common.core.constant.UserConstants;
|
||||
import com.pusong.common.core.domain.model.LoginUser;
|
||||
import com.pusong.common.core.exception.ServiceException;
|
||||
import com.pusong.common.core.service.DictService;
|
||||
import com.pusong.common.core.utils.DateUtils;
|
||||
import com.pusong.common.core.utils.MapstructUtils;
|
||||
import com.pusong.common.core.utils.StringUtils;
|
||||
import com.pusong.common.doc.util.NumBerTool;
|
||||
import com.pusong.common.doc.util.PdfGenerator;
|
||||
import com.pusong.common.mybatis.core.page.TableDataInfo;
|
||||
import com.pusong.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pusong.common.satoken.utils.LoginHelper;
|
||||
import com.pusong.system.domain.SysDictData;
|
||||
import com.pusong.system.domain.vo.SysOssVo;
|
||||
import com.pusong.system.service.ISysDictDataService;
|
||||
import com.pusong.system.service.ISysOssService;
|
||||
import jakarta.annotation.Resource;
|
||||
import jodd.util.StringUtil;
|
||||
@ -34,6 +39,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -66,6 +72,13 @@ public class PsContractInfoServiceImpl implements IPsContractInfoService {
|
||||
private final ApproverContainer container;
|
||||
|
||||
private final IPsTaskService taskMainService;
|
||||
|
||||
private final ISysDictDataService dictDataService;
|
||||
public static String getContractCode(){
|
||||
Random random = new Random();
|
||||
int randomNumber = random.nextInt(8999) + 1000;
|
||||
return DateUtils.parseDateToStr("yyyyMMddHHmm",new Date())+randomNumber;
|
||||
}
|
||||
/**
|
||||
* 生成合同
|
||||
*
|
||||
@ -84,8 +97,9 @@ public class PsContractInfoServiceImpl implements IPsContractInfoService {
|
||||
if(add == null){
|
||||
add = new PsContractInfo();
|
||||
MapstructUtils.convert(bo, add);
|
||||
add.setContractCode(UUID.randomUUID().toString().replaceAll("-", ""));//合同编码
|
||||
add.setContractName("合同名称");//todo 合同名称
|
||||
add.setContractCode(getContractCode());//合同编码
|
||||
// 合同名称:公司名+合同编码
|
||||
add.setContractName(bo.getCompanyInfoBo().getCompanyName()+add.getContractCode());
|
||||
add.setCustomManager(LoginHelper.getUserId());//所属销售经理id
|
||||
}else{
|
||||
MapstructUtils.convert(bo, add);
|
||||
@ -120,11 +134,22 @@ public class PsContractInfoServiceImpl implements IPsContractInfoService {
|
||||
public Long preview(PsContractInfoBo bo){
|
||||
//3.如果已存在合同,则进行修改,否则新增
|
||||
PsContractInfo add = new PsContractInfo();
|
||||
add.setContractCode("0000000000-1");//合同编码
|
||||
add.setContractName("合同名称");//todo 合同名称
|
||||
add.setContractCode(getContractCode());//合同编码
|
||||
// 合同名称:公司名+合同编码
|
||||
add.setContractName(bo.getCompanyInfoBo().getCompanyName()+add.getContractCode());
|
||||
add.setCustomManager(LoginHelper.getUserId());//所属销售经理id
|
||||
add.setCompanyId(bo.getCompanyInfoBo().getId());//公司id
|
||||
MapstructUtils.convert(bo, add);
|
||||
bo.getBusinessList().forEach(item->{
|
||||
BigDecimal mony = BigDecimal.ZERO;
|
||||
if(CollectionUtils.isNotEmpty(item.getDetailBos())){
|
||||
mony = item.getDetailBos().stream().map(PsContractBusinessDetailBo::getAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
//服务类别填了才会修改服务项目的金额
|
||||
if(mony.compareTo(BigDecimal.ZERO) > 0){
|
||||
item.setBusinessAmount(mony);
|
||||
}
|
||||
});
|
||||
BigDecimal sum = bo.getBusinessList().stream().map(PsContractBusinessBo::getBusinessAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
add.setContractAmount(sum);//合同总金额
|
||||
return makePdf(add,bo);
|
||||
@ -309,14 +334,20 @@ public class PsContractInfoServiceImpl implements IPsContractInfoService {
|
||||
*/
|
||||
public Long makePdf(PsContractInfo add ,PsContractInfoBo bo){
|
||||
Long ossId = null;
|
||||
SysDictData main = dictDataService.selectDict("contract_main", add.getContractMain());
|
||||
try{
|
||||
//生成合同pdf
|
||||
PsCustomInfo customer = customInfoService.listById(add.getCustomId());
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
LoginUser user = LoginHelper.getLoginUser();
|
||||
map.put("user",user);
|
||||
map.put("contract",add);
|
||||
map.put("business",bo.getBusinessList());
|
||||
map.put("main",JSON.parseObject(main.getRemark()));// 合同主体信息
|
||||
map.put("company",bo.getCompanyInfoBo());
|
||||
map.put("customer",customer);
|
||||
// 合同总金额大写
|
||||
map.put("contractAmount", NumBerTool.digitUppercase(add.getContractAmount().setScale(2, RoundingMode.HALF_EVEN).toString()));
|
||||
String head = "合同编号:PS-"+add.getContractCode()+" 客户编号:"+customer.getId();
|
||||
//合同标题
|
||||
map.put(PdfGenerator.HEAD,head);
|
||||
|
@ -2,6 +2,7 @@ package com.pusong.system.service;
|
||||
|
||||
import com.pusong.common.mybatis.core.page.PageQuery;
|
||||
import com.pusong.common.mybatis.core.page.TableDataInfo;
|
||||
import com.pusong.system.domain.SysDictData;
|
||||
import com.pusong.system.domain.bo.SysDictDataBo;
|
||||
import com.pusong.system.domain.vo.SysDictDataVo;
|
||||
|
||||
@ -34,6 +35,15 @@ public interface ISysDictDataService {
|
||||
*/
|
||||
String selectDictLabel(String dictType, String dictValue);
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典键值查询字典数据信息
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典键值
|
||||
* @return 字典对象
|
||||
*/
|
||||
SysDictData selectDict(String dictType, String dictValue);
|
||||
|
||||
/**
|
||||
* 根据字典数据ID查询信息
|
||||
*
|
||||
|
@ -79,6 +79,20 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
|
||||
.getDictLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型和字典键值查询字典数据信息
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @param dictValue 字典键值
|
||||
* @return 字典标签
|
||||
*/
|
||||
@Override
|
||||
public SysDictData selectDict(String dictType, String dictValue) {
|
||||
return baseMapper.selectOne(new LambdaQueryWrapper<SysDictData>()
|
||||
.eq(SysDictData::getDictType, dictType)
|
||||
.eq(SysDictData::getDictValue, dictValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典数据ID查询信息
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user