新增专家签名导出pdf
This commit is contained in:
@ -39,6 +39,10 @@ spec:
|
||||
- name: log
|
||||
hostPath:
|
||||
path: /var/lib/docker/log/349553515466-test/default-group/all #开发环境
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: file-pvc
|
||||
readOnly: false
|
||||
# 必选,Pod中容器列表
|
||||
containers:
|
||||
- name: biz-service-ebtp-extend
|
||||
@ -47,6 +51,8 @@ spec:
|
||||
volumeMounts:
|
||||
- name: log
|
||||
mountPath: /log
|
||||
- name: storage
|
||||
mountPath: /storage
|
||||
# 需要暴露的端口库号列表
|
||||
ports:
|
||||
- containerPort: 18018
|
||||
|
@ -39,6 +39,10 @@ spec:
|
||||
- name: log
|
||||
hostPath:
|
||||
path: /var/lib/docker/log/349553515466-prod/default-group/30days
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: file-pvc
|
||||
readOnly: false
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
@ -57,6 +61,8 @@ spec:
|
||||
volumeMounts:
|
||||
- name: log
|
||||
mountPath: /log
|
||||
- name: storage
|
||||
mountPath: /storage
|
||||
ports:
|
||||
- containerPort: 18018
|
||||
livenessProbe:
|
||||
|
@ -39,6 +39,10 @@ spec:
|
||||
- name: log
|
||||
hostPath:
|
||||
path: /var/lib/docker/log/349553515466-preprod/default-group/all #开发环境
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: file-pvc
|
||||
readOnly: false
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
@ -57,6 +61,8 @@ spec:
|
||||
volumeMounts:
|
||||
- name: log
|
||||
mountPath: /log
|
||||
- name: storage
|
||||
mountPath: /storage
|
||||
ports:
|
||||
- containerPort: 18018
|
||||
resources:
|
||||
|
@ -40,7 +40,10 @@ spec:
|
||||
- name: log
|
||||
hostPath:
|
||||
path: /var/lib/docker/log/349553515466-uat/default-group/all #开发环境
|
||||
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: file-pvc
|
||||
readOnly: false
|
||||
# 必选,Pod中容器列表
|
||||
containers:
|
||||
- name: biz-service-ebtp-extend
|
||||
@ -49,6 +52,8 @@ spec:
|
||||
volumeMounts:
|
||||
- name: log
|
||||
mountPath: /log
|
||||
- name: storage
|
||||
mountPath: /storage
|
||||
# 需要暴露的端口库号列表
|
||||
ports:
|
||||
- containerPort: 18018
|
||||
|
BIN
lib/aspose-words-16.8.0-javadoc.jar
Normal file
BIN
lib/aspose-words-16.8.0-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/aspose-words-16.8.0-jdk16.jar
Normal file
BIN
lib/aspose-words-16.8.0-jdk16.jar
Normal file
Binary file not shown.
27
pom.xml
27
pom.xml
@ -71,6 +71,7 @@
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jit.vstk</groupId>
|
||||
<artifactId>jit-vstk</artifactId>
|
||||
@ -78,6 +79,21 @@
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/jit-vstk-jdk15-2.0.50-20150603.060911-1.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>aspose.javadoc</groupId>
|
||||
<artifactId>aspose.javadoc</artifactId>
|
||||
<version>16.8.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/aspose-words-16.8.0-javadoc.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>aspose.jdk16</groupId>
|
||||
<artifactId>aspose.jdk16</artifactId>
|
||||
<version>16.8.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/aspose-words-16.8.0-jdk16.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-tools</artifactId>
|
||||
@ -89,7 +105,11 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>e-iceblue</groupId>
|
||||
<artifactId>spire.doc.free</artifactId>
|
||||
<version>3.9.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
@ -105,6 +125,11 @@
|
||||
<updatePolicy>always</updatePolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>com.e-iceblue</id>
|
||||
<url>http://repo.e-iceblue.cn/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
|
@ -0,0 +1,41 @@
|
||||
package com.chinaunicom.mall.ebtp.extend.signature.controller;
|
||||
|
||||
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
|
||||
import com.chinaunicom.mall.ebtp.extend.signature.entity.ExpertSignature;
|
||||
import com.chinaunicom.mall.ebtp.extend.signature.service.ExpertSignatureService;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
@RestController
|
||||
@Api(tags = "")
|
||||
@RequestMapping("/v1/sign")
|
||||
public class ExpertSignatureController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private ExpertSignatureService expertSignatureService;
|
||||
|
||||
/**
|
||||
* 追加专家签名
|
||||
*
|
||||
* @param signature
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
@PreAuthorize("hasAnyAuthority('ebtp-purchase','ebtp-agency-project-manager')")
|
||||
@PostMapping(value = "")
|
||||
public BaseResponse<String> export(@RequestBody ExpertSignature signature, HttpServletRequest request, HttpServletResponse response) {
|
||||
return BaseResponse.success(expertSignatureService.addSignature(signature));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.chinaunicom.mall.ebtp.extend.signature.entity;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ExpertInfo {
|
||||
|
||||
private String expertId;
|
||||
|
||||
private String expertSign;
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.chinaunicom.mall.ebtp.extend.signature.entity;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ExpertSignature {
|
||||
|
||||
private String assessRoomId;
|
||||
|
||||
private String bid;
|
||||
|
||||
private List<ExpertInfo> experts;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.chinaunicom.mall.ebtp.extend.signature.service;
|
||||
|
||||
import com.chinaunicom.mall.ebtp.extend.signature.entity.ExpertSignature;
|
||||
|
||||
public interface ExpertSignatureService {
|
||||
|
||||
|
||||
/**
|
||||
* 追加专家签名
|
||||
*
|
||||
* @param signature
|
||||
* @return
|
||||
*/
|
||||
String addSignature(ExpertSignature signature);
|
||||
}
|
@ -0,0 +1,228 @@
|
||||
package com.chinaunicom.mall.ebtp.extend.signature.service.impl;
|
||||
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.aspose.words.License;
|
||||
import com.aspose.words.SaveFormat;
|
||||
import com.chinaunicom.ebtp.mall.cloud.attachment.sdk.api.AttachmentClient;
|
||||
import com.chinaunicom.ebtp.mall.cloud.attachment.sdk.model.AttachmentEntity;
|
||||
import com.chinaunicom.mall.ebtp.common.util.PropertyUtils;
|
||||
import com.chinaunicom.mall.ebtp.extend.export.service.templateFile.TemplateFileService;
|
||||
import com.chinaunicom.mall.ebtp.extend.signature.entity.ExpertSignature;
|
||||
import com.chinaunicom.mall.ebtp.extend.signature.service.ExpertSignatureService;
|
||||
import com.deepoove.poi.XWPFTemplate;
|
||||
import com.deepoove.poi.data.PictureRenderData;
|
||||
import com.spire.doc.Document;
|
||||
import com.spire.doc.DocumentObject;
|
||||
import com.spire.doc.FileFormat;
|
||||
import com.spire.doc.Section;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import sun.misc.BASE64Decoder;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ExpertSignatureServiceImpl implements ExpertSignatureService {
|
||||
|
||||
@Autowired
|
||||
private AttachmentClient attachmentClient;
|
||||
|
||||
@Autowired
|
||||
private TemplateFileService templateFileService;
|
||||
|
||||
@Value("${mconfig.file.upload-address}")
|
||||
private String uploadAddress;
|
||||
|
||||
|
||||
private String getUploadAddress(String assessRoomId) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
|
||||
return uploadAddress + File.separator + sdf.format(System.currentTimeMillis()) + File.separator + assessRoomId + File.separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加专家签名
|
||||
*
|
||||
* @param signature
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String addSignature(ExpertSignature signature) {
|
||||
//获取临时存储地址
|
||||
String path = this.getUploadAddress(signature.getAssessRoomId());
|
||||
//获取专家签名文件
|
||||
InputStream expertSign = getExpertSign(signature, path);
|
||||
//获取bid的word文件
|
||||
AttachmentEntity entity = attachmentClient.findByObjectId(signature.getBid()).orElse(new AttachmentEntity());
|
||||
|
||||
byte[] bytes = attachmentClient.downloadFileByObjectId(signature.getBid()).orElse(new byte[0]);
|
||||
InputStream word = new ByteArrayInputStream(bytes);
|
||||
|
||||
//合并word 转为pdf
|
||||
byte[] pdf = null;
|
||||
try {
|
||||
pdf = mergeWord(word, expertSign, path);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//上传pdf到文档中心
|
||||
String pdfId = PropertyUtils.getSnowflakeId();
|
||||
attachmentClient.upload(pdfId, entity.getFilename(), pdf);
|
||||
return pdfId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并word
|
||||
*
|
||||
* @param source
|
||||
* @param addObj
|
||||
* @param path
|
||||
* @throws IOException
|
||||
*/
|
||||
private byte[] mergeWord(InputStream source, InputStream addObj, String path) throws IOException {
|
||||
Document d1 = new Document(source);
|
||||
Document d2 = new Document(addObj);
|
||||
|
||||
//获取文档1的最后一节
|
||||
Section lastsec = d1.getLastSection();
|
||||
|
||||
//遍历文档2的所有段落内容,添加到文档1
|
||||
for (Section section : (Iterable<Section>) d2.getSections()) {
|
||||
for (DocumentObject obj : (Iterable<DocumentObject>) section.getBody().getChildObjects()
|
||||
) {
|
||||
lastsec.getBody().getChildObjects().add(obj.deepClone());
|
||||
}
|
||||
}
|
||||
|
||||
//保存合并后的文档
|
||||
d1.saveToFile(path + "/merged.docx", FileFormat.Docx_2010);
|
||||
|
||||
//转为pdf
|
||||
long l = System.currentTimeMillis();
|
||||
if (!getLicense()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
File f = new File(path + "/merged.pdf");
|
||||
FileOutputStream fos = new FileOutputStream(f);
|
||||
|
||||
try {
|
||||
com.aspose.words.Document doc = new com.aspose.words.Document(path + "/merged.docx");
|
||||
doc.save(fos, SaveFormat.PDF);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
source.close();
|
||||
addObj.close();
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
long l1 = System.currentTimeMillis();
|
||||
log.info(" ======= " + (l1 - l) + " ======= ");
|
||||
|
||||
return IOUtils.toByteArray(new FileInputStream(f));
|
||||
}
|
||||
|
||||
private boolean getLicense() {
|
||||
boolean result = false;
|
||||
InputStream is = ExpertSignatureServiceImpl.class.getClassLoader().getResourceAsStream("/license/aspose-license.xml");
|
||||
// String licenseStr =
|
||||
// "<License>\n" +
|
||||
// " <Data>\n" +
|
||||
// " <Products>\n" +
|
||||
// " <Product>Aspose.Total for Java</Product>\n" +
|
||||
// " <Product>Aspose.Words for Java</Product>\n" +
|
||||
// " </Products>\n" +
|
||||
// " <EditionType>Enterprise</EditionType>\n" +
|
||||
// " <SubscriptionExpiry>20991231</SubscriptionExpiry>\n" +
|
||||
// " <LicenseExpiry>20991231</LicenseExpiry>\n" +
|
||||
// " <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>\n" +
|
||||
// " </Data>\n" +
|
||||
// " <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>\n" +
|
||||
// "</License>";
|
||||
// InputStream is = null;
|
||||
// is = new ByteArrayInputStream(licenseStr.getBytes(StandardCharsets.UTF_8));
|
||||
License license = new License();
|
||||
try {
|
||||
license.setLicense(is);
|
||||
result = true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private FileInputStream getExpertSign(ExpertSignature signature, final String path) {
|
||||
String imgPath = path + "/imgs/";
|
||||
if (!FileUtil.exist(imgPath)) {
|
||||
FileUtil.mkdir(imgPath);
|
||||
}
|
||||
List<PictureRenderData> pics = new ArrayList<>();
|
||||
signature.getExperts().forEach(l -> {
|
||||
base64ToImage(l.getExpertSign(), imgPath + l.getExpertId());
|
||||
|
||||
pics.add(new PictureRenderData(130, 100, imgPath + l.getExpertId()));
|
||||
});
|
||||
|
||||
//获取签名模版
|
||||
InputStream file = templateFileService.getExportTemplet("expertSignature");
|
||||
|
||||
//生成签名word
|
||||
Map<String, Object> all = new HashMap<String, Object>() {{
|
||||
put("imgs", pics);
|
||||
}};
|
||||
XWPFTemplate template = XWPFTemplate.compile(file).render(all);
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
String docPath = path + "/expertSignature.docx";
|
||||
template.writeToFile(docPath);
|
||||
fis = new FileInputStream(new File(docPath));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return fis;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* base64字符串转换成图片
|
||||
*
|
||||
* @param imgStr base64字符串
|
||||
* @param imgFilePath 图片存放路径
|
||||
*/
|
||||
private void base64ToImage(String imgStr, String imgFilePath) {
|
||||
if (StringUtils.isEmpty(imgStr)) {
|
||||
return;
|
||||
}
|
||||
BASE64Decoder decoder = new BASE64Decoder();
|
||||
try {
|
||||
// Base64解码
|
||||
byte[] b = decoder.decodeBuffer(imgStr);
|
||||
for (int i = 0; i < b.length; ++i) {
|
||||
if (b[i] < 0) {// 调整异常数据
|
||||
b[i] += 256;
|
||||
}
|
||||
}
|
||||
OutputStream out = new FileOutputStream(imgFilePath);
|
||||
out.write(b);
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -172,9 +172,13 @@ mconfig:
|
||||
tender: biz-service-ebtp-tender #投标服务
|
||||
documentcenter: core-service-document-center #文档中心
|
||||
usercenter: core-service-usercenter-public #用户中心
|
||||
file:
|
||||
upload-address: /storage/reviewReport/
|
||||
document:
|
||||
clientHttpUrl: http://10.242.31.158:8100/auth/oauth/token?grant_type=client_credentials&client_id=bVS46ElU&client_secret=58ea04ba02475c8da2321cc99849d2a10f15b749
|
||||
|
||||
|
||||
|
||||
# 用户暴露给 prometheus 的健康数据
|
||||
management:
|
||||
endpoints:
|
||||
|
@ -3,18 +3,18 @@ server:
|
||||
servlet:
|
||||
context-path: /
|
||||
|
||||
# 对应 apollo 配置中心的应用名
|
||||
app:
|
||||
id: biz-service-ebtp-extend
|
||||
|
||||
# Apollo 配置信息
|
||||
apollo:
|
||||
meta: http://10.242.37.148:6001/
|
||||
bootstrap:
|
||||
namespace: application
|
||||
enabled: true
|
||||
eagerLoad:
|
||||
enabled: true
|
||||
## 对应 apollo 配置中心的应用名
|
||||
#app:
|
||||
# id: biz-service-ebtp-extend
|
||||
#
|
||||
## Apollo 配置信息
|
||||
#apollo:
|
||||
# meta: http://10.242.37.148:6001/
|
||||
# bootstrap:
|
||||
# namespace: application
|
||||
# enabled: true
|
||||
# eagerLoad:
|
||||
# enabled: true
|
||||
|
||||
seata:
|
||||
service:
|
||||
@ -164,7 +164,8 @@ mconfig:
|
||||
tender: biz-service-ebtp-tender #投标服务
|
||||
documentcenter: core-service-document-center #文档中心
|
||||
usercenter: core-service-usercenter-public #用户中心
|
||||
|
||||
file:
|
||||
upload-address: /storage/reviewReport/
|
||||
|
||||
document:
|
||||
clientHttpUrl: http://10.242.31.158:8100/auth/oauth/token?grant_type=client_credentials&client_id=bVS46ElU&client_secret=58ea04ba02475c8da2321cc99849d2a10f15b749
|
||||
|
@ -167,6 +167,8 @@ mconfig:
|
||||
tender: biz-service-ebtp-tender #投标服务
|
||||
documentcenter: core-service-document-center #文档中心
|
||||
usercenter: core-service-usercenter-public #用户中心
|
||||
file:
|
||||
upload-address: /storage/reviewReport/
|
||||
document:
|
||||
clientHttpUrl: http://10.238.25.112:8100/auth/oauth/token?grant_type=client_credentials&client_id=bVS46ElU&client_secret=58ea04ba02475c8da2321cc99849d2a10f15b749
|
||||
|
||||
|
@ -167,6 +167,8 @@ mconfig:
|
||||
tender: biz-service-ebtp-tender #投标服务
|
||||
documentcenter: core-service-document-center #文档中心
|
||||
usercenter: core-service-usercenter-public #用户中心
|
||||
file:
|
||||
upload-address: /storage/reviewReport/
|
||||
document:
|
||||
clientHttpUrl: http://10.242.31.158:8100/auth/oauth/token?grant_type=client_credentials&client_id=bVS46ElU&client_secret=58ea04ba02475c8da2321cc99849d2a10f15b749
|
||||
|
||||
|
16
src/main/resources/license/aspose-license.xml
Normal file
16
src/main/resources/license/aspose-license.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<License>
|
||||
<Data>
|
||||
<Products>
|
||||
<Product>Aspose.Total for Java</Product>
|
||||
<Product>Aspose.Words for Java</Product>
|
||||
</Products>
|
||||
<EditionType>Enterprise</EditionType>
|
||||
<SubscriptionExpiry>20991231</SubscriptionExpiry>
|
||||
<LicenseExpiry>20991231</LicenseExpiry>
|
||||
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
|
||||
</Data>
|
||||
<Signature>
|
||||
sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
|
||||
</Signature>
|
||||
</License>
|
Reference in New Issue
Block a user