diff --git a/pom.xml b/pom.xml
index 0553bb8..cd0760d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -242,14 +242,31 @@
core
3.3.0
-
-
com.google.zxing
javase
3.3.0
+
+ org.docx4j
+ docx4j
+ 6.1.2
+
+
+
+
+ com.itextpdf
+ itextpdf
+ 5.5.13
+
+
+ com.itextpdf
+ itext-asian
+ 5.2.0
+
+
+
@@ -282,5 +299,13 @@
+
+
+
+ aspose-maven-repository
+ http://artifact.aspose.com/repo/
+
+
+
diff --git a/simyou.TTF b/simyou.TTF
new file mode 100644
index 0000000..4a8f27e
Binary files /dev/null and b/simyou.TTF differ
diff --git a/src/main/java/com/xkrs/controller/SysUserController.java b/src/main/java/com/xkrs/controller/SysUserController.java
index af97cd6..f81546a 100644
--- a/src/main/java/com/xkrs/controller/SysUserController.java
+++ b/src/main/java/com/xkrs/controller/SysUserController.java
@@ -317,7 +317,7 @@ public class SysUserController {
}
/**
- * 用户修改密码
+ * 用户修改账号密码
* @param map
* @param token
* @return
diff --git a/src/main/java/com/xkrs/utils/ElectronicContractUtil.java b/src/main/java/com/xkrs/utils/ElectronicContractUtil.java
new file mode 100644
index 0000000..054ab52
--- /dev/null
+++ b/src/main/java/com/xkrs/utils/ElectronicContractUtil.java
@@ -0,0 +1,130 @@
+package com.xkrs.utils;
+
+import cn.hutool.core.date.DateUtil;
+import com.itextpdf.text.Image;
+import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.pdf.*;
+
+import java.io.*;
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * @Author: XinYi Song
+ * @Date: 2022/1/6 15:45
+ */
+public class ElectronicContractUtil {
+
+ /**
+ * 根据PDF模版生成PDF文件
+ * @param templateFilePath PDF模版文件路径
+ * @param data 表单数据
+ * @param imageData 图片数据 VALUE为图片文件路径
+ * @param formFlattening false:生成后的PDF文件表单域仍然可编辑 true:生成后的PDF文件表单域不可编辑
+ * @param pdfFilePath 生成PDF的文件路径
+ */
+ private static void createPDF(String templateFilePath, HashMap data, HashMap imageData,
+ boolean formFlattening, String pdfFilePath) throws Exception{
+ PdfReader reader = null;
+ ByteArrayOutputStream bos = null;
+ PdfStamper pdfStamper = null;
+ FileOutputStream fos = null;
+ try{
+ // 读取PDF模版文件
+ reader = new PdfReader(templateFilePath);
+ // 输出流
+ bos = new ByteArrayOutputStream();
+ // 构建PDF对象
+ pdfStamper = new PdfStamper(reader, bos);
+
+ // 获取表单数据
+ AcroFields form = pdfStamper.getAcroFields();
+
+ // 使用中文字体 使用 AcroFields填充值的不需要在程序中设置字体,在模板文件中设置字体为中文字体 Adobe 宋体 std L
+ BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
+ form.addSubstitutionFont(bfChinese);
+
+ // 表单赋值
+ for(String key : data.keySet()){
+ form.setField(key,data.get(key));
+ // 也可以指定字体
+ form.setFieldProperty(key, "textfont", bfChinese, null);
+ }
+
+ if(null != imageData && imageData.size() > 0){
+ for(String key : imageData.keySet()){
+ int pageNo = form.getFieldPositions(key).get(0).page;
+ Rectangle signRect = form.getFieldPositions(key).get(0).position;
+ float x = signRect.getLeft();
+ float y = signRect.getBottom();
+ // 读图片
+ Image image = Image.getInstance(imageData.get(key));
+ // 获取操作的页面
+ PdfContentByte under = pdfStamper.getOverContent(pageNo);
+ // 根据域的大小缩放图片
+ image.scaleToFit(signRect.getWidth(), signRect.getHeight());
+ // 添加图片
+ image.setAbsolutePosition(x, y);
+ under.addImage(image);
+ }
+ }
+
+ // 如果为false那么生成的PDF文件还能编辑,一定要设为true
+ pdfStamper.setFormFlattening(formFlattening);
+ pdfStamper.close();
+
+ // 保存文件
+ fos = new FileOutputStream(pdfFilePath);
+ fos.write(bos.toByteArray());
+ fos.flush();
+ }finally {
+ if(null != fos){
+ try {fos.close(); }catch (Exception e){e.printStackTrace();}
+ }
+
+ if(null != bos){
+ try {bos.close(); }catch (Exception e){e.printStackTrace();}
+ }
+
+ if(null != reader){
+ try {reader.close(); }catch (Exception e){e.printStackTrace();}
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ // 模版文件
+ String templateFilePath = "E:/shop/乐益播联盟商家入驻协议(APP版)(1).pdf";
+ // 保存PDF文件
+ String fileCode = System.currentTimeMillis()+"";
+ String pdfFilePath = "E:/shoptest/"+fileCode+".pdf";
+ // 电子签名图片
+ String signImg = "E:/shop/1.jpg";
+
+ // 表单数据
+ HashMap data = new HashMap<>();
+ data.put("contacts","宋");
+ data.put("telephone","15315526196");
+ data.put("name","星科瑞升");
+
+ data.put("discount","2");
+
+ data.put("monthone","01");
+ data.put("dayone","11");
+ data.put("year","3");
+
+ data.put("monthtwo","01");
+
+ data.put("daytwo","23");
+ data.put("monththree","03");
+ data.put("daythree","01");
+
+ // 图片数据
+ HashMap imageData = new HashMap<>();
+ imageData.put("sign",signImg);
+
+ // 根据PDF模版生成PDF文件
+ createPDF(templateFilePath,data,imageData,true,pdfFilePath);
+ }
+}
diff --git a/src/main/java/com/xkrs/utils/Graphics2DUtil.java b/src/main/java/com/xkrs/utils/Graphics2DUtil.java
new file mode 100644
index 0000000..959b148
--- /dev/null
+++ b/src/main/java/com/xkrs/utils/Graphics2DUtil.java
@@ -0,0 +1,174 @@
+package com.xkrs.utils;
+
+import javax.imageio.ImageIO;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Transparency;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.util.Date;
+
+public class Graphics2DUtil {
+
+ private static final int WIDTH = 500;//图片宽度
+ private static final int HEIGHT = 500;//图片高度
+ private static String message = "芜羡科技有限公司";
+ private static String centerName = "测试章";
+ private static String year = "2018年06月11日";
+
+
+
+ public static void main(String[] args) throws Exception{
+ BufferedImage image = startGraphics2D();
+ try {
+ String filePath = "D:\\"+System.currentTimeMillis()+".png";
+ ImageIO.write(image, "png", new File(filePath)); //将其保存在D:\\下,得有这个目录
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public static BufferedImage startGraphics2D(){
+ // 定义图像buffer
+ BufferedImage buffImg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = buffImg.createGraphics();
+ // 增加下面代码使得背景透明
+ buffImg = g.getDeviceConfiguration().createCompatibleImage(WIDTH, HEIGHT, Transparency.TRANSLUCENT);
+ g.dispose();
+ g = buffImg.createGraphics();
+ // 背景透明代码结束
+
+ g.setColor(Color.RED);
+ //设置锯齿圆滑
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ //绘制圆
+ int radius = HEIGHT/3;//周半径
+ int CENTERX = WIDTH/2;//画图所出位置
+ int CENTERY = HEIGHT/2;//画图所处位置
+
+ Ellipse2D circle = new Ellipse2D.Double();
+ circle.setFrameFromCenter(CENTERX, CENTERY, CENTERX + radius, CENTERY + radius);
+ g.setStroke(new BasicStroke(10));//设置圆的宽度
+ g.draw(circle);
+
+ //绘制中间的五角星
+ g.setFont(new Font("宋体", Font.BOLD, 120));
+ g.drawString("★", CENTERX-(120/2), CENTERY+(120/3));
+
+ //添加姓名
+ g.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 30));// 写入签名
+ g.drawString(centerName, CENTERX -(40), CENTERY +(30+50));
+
+ //添加年份
+ g.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 20));// 写入签名
+ g.drawString(year, CENTERX -(60), CENTERY +(30+80));
+
+ //根据输入字符串得到字符数组
+ String[] messages2 = message.split("",0);
+ String[] messages = new String[messages2.length-1];
+ System.arraycopy(messages2,1,messages,0,messages2.length-1);
+
+ //输入的字数
+ int ilength = messages.length;
+
+ //设置字体属性
+ int fontsize = 40;
+ Font f = new Font("Serif", Font.BOLD, fontsize);
+
+ FontRenderContext context = g.getFontRenderContext();
+ Rectangle2D bounds = f.getStringBounds(message, context);
+
+ //字符宽度=字符串长度/字符数
+ double char_interval = (bounds.getWidth() / ilength);
+ //上坡度
+ double ascent = -bounds.getY();
+
+ int first = 0,second = 0;
+ boolean odd = false;
+ if (ilength%2 == 1)
+ {
+ first = (ilength-1)/2;
+ odd = true;
+ }
+ else
+ {
+ first = (ilength)/2-1;
+ second = (ilength)/2;
+ odd = false;
+ }
+
+ double radius2 = radius - ascent;
+ double x0 = CENTERX;
+ double y0 = CENTERY - radius + ascent;
+ //旋转角度
+ double a = 2*Math.asin(char_interval/(2*radius2));
+
+ if (odd)
+ {
+ g.setFont(f);
+ g.drawString(messages[first], (float)(x0 - char_interval/2), (float)y0);
+
+ //中心点的右边
+ for (int i=first+1;i-1;i--)
+ {
+ double aa = (first - i) * a;
+ double ax = radius2 * Math.sin(aa);
+ double ay = radius2 - radius2 * Math.cos(aa);
+ AffineTransform transform = AffineTransform.getRotateInstance(-aa);//,x0 + ax, y0 + ay);
+ Font f2 = f.deriveFont(transform);
+ g.setFont(f2);
+ g.drawString(messages[i], (float)(x0 - ax - char_interval/2* Math.cos(aa)), (float)(y0 + ay + char_interval/2* Math.sin(aa)));
+ }
+
+ }
+ else
+ {
+ //中心点的右边
+ for (int i=second;i-1;i--)
+ {
+ double aa = (first - i + 0.5) * a;
+ double ax = radius2 * Math.sin(aa);
+ double ay = radius2 - radius2 * Math.cos(aa);
+ AffineTransform transform = AffineTransform.getRotateInstance(-aa);//,x0 + ax, y0 + ay);
+ Font f2 = f.deriveFont(transform);
+ g.setFont(f2);
+ g.drawString(messages[i], (float)(x0 - ax - char_interval/2* Math.cos(aa)), (float)(y0 + ay + char_interval/2* Math.sin(aa)));
+ }
+ }
+
+ return buffImg;
+ }
+
+
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 6650003..26db9cf 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,4 +1,4 @@
-server.port = 6801
+server.port = 6802
## 数据源配置
spring.datasource.url = jdbc:mysql://rm-bp160630z03x880745o.mysql.rds.aliyuncs.com:3306/leyibo_business?useSSL=false&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai
diff --git a/src/main/resources/docx4j.properties b/src/main/resources/docx4j.properties
new file mode 100644
index 0000000..54827b8
--- /dev/null
+++ b/src/main/resources/docx4j.properties
@@ -0,0 +1,25 @@
+# Page size: use a value from org.docx4j.model.structure.PageSizePaper enum
+# eg A4, LETTER
+docx4j.PageSize=LETTER
+# Page size: use a value from org.docx4j.model.structure.MarginsWellKnown enum
+docx4j.PageMargins=NORMAL
+docx4j.PageOrientationLandscape=false
+# Page size: use a value from org.pptx4j.model.SlideSizesWellKnown enum
+# eg A4, LETTER
+pptx4j.PageSize=LETTER
+pptx4j.PageOrientationLandscape=false
+# These will be injected into docProps/app.xml
+# if App.Write=true
+docx4j.App.write=true
+docx4j.Application=docx4j
+docx4j.AppVersion=6.1.2
+# of the form XX.YYYY where X and Y represent numerical values
+# These will be injected into docProps/core.xml
+docx4j.dc.write=true
+docx4j.dc.creator.value=docx4j
+docx4j.dc.lastModifiedBy.value=docx4j
+#
+#docx4j.McPreprocessor=true
+# If you haven't configured log4j yourself
+# docx4j will autoconfigure it. Set this to true to disable that
+docx4j.Log4j.Configurator.disabled=false
\ No newline at end of file