crm-print/server/src/main/java/cn/keking/service/ContractService.java

273 lines
10 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cn.keking.service;
import cn.afterturn.easypoi.word.WordExportUtil;
import cn.keking.config.ConfigConstants;
import cn.keking.config.KkfileConfig;
import cn.keking.exception.KkFileException;
import cn.keking.service.impl.OtherFilePreviewImpl;
import cn.keking.utils.Consts;
import cn.keking.utils.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.HtmlUtils;
import javax.annotation.Resource;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author Hikaru
*/
@Service
@Slf4j
public class ContractService {
/**
* 配置常量
*/
@Resource
private ConfigConstants configConstants;
/**
* kkfile配置
*/
@Resource
private KkfileConfig kkfileConfig;
private final OfficeToPdfService officeToPdfService;
public ContractService(FileHandlerService fileHandlerService, OfficeToPdfService officeToPdfService, OtherFilePreviewImpl otherFilePreview) {
this.officeToPdfService = officeToPdfService;
}
/**
* 上传
*
* @param templateName 模板名
* @param multipartFile 模板文件
* @return 路径
* @throws IOException 异常
*/
public String upload(String templateName, MultipartFile multipartFile) {
if (multipartFile == null) {
throw new KkFileException("上传文件不能为空");
}
// 获取文件名
String fileName = multipartFile.getOriginalFilename();
fileName = HtmlUtils.htmlEscape(fileName, StandardCharsets.UTF_8.name());
//获取文件大小 文件大小不超过10m
long size = multipartFile.getSize();
if (size > kkfileConfig.getTemplateMaxSize()) {
long currentSizeM = kkfileConfig.getTemplateMaxSize() / 1024 / 1024;
throw new KkFileException("上传的文件限制大小为" + currentSizeM + "m");
}
//获取文件扩展名目前模板只支持docx
String extensionName = getExtension(fileName);
if (!kkfileConfig.getAllowUploadType().contains(extensionName)) {
throw new KkFileException("不支持的文件类型【" + extensionName + "");
}
//目录不存在重新生成目录
File outFile = new File(Consts.getTemplatePath());
if (!outFile.exists() && !outFile.mkdirs()) {
log.error("创建文件夹【{}】失败,请检查目录权限!", Consts.getTemplatePath());
}
String newFileName = templateName + "." + extensionName;
String url = this.configConstants.getBaseUrl() + "/" + Consts.TEMPLATE_PATH_NAME + "/" + templateName + "." + extensionName;
String filePath = Consts.getTemplatePath() + File.separator + newFileName;
log.info("上传文件:{}", filePath);
try (InputStream in = multipartFile.getInputStream(); OutputStream out = new FileOutputStream(filePath)) {
StreamUtils.copy(in, out);
} catch (Exception e) {
log.error("文件拷贝失败:", e);
throw new KkFileException("文件拷贝失败");
}
return url;
}
/**
* 查询所有模板url
*
* @param templateNames 模板名称
* @return 模板url
*/
public List<String> listTemplate(List<String> templateNames) {
return templateNames.stream().map(s -> downUrl(s, "docx")).collect(Collectors.toList());
}
private String downUrl(String templateName, String extensionName) {
return this.configConstants.getBaseUrl() + "/" + Consts.TEMPLATE_PATH_NAME + "/" + templateName + "." + extensionName;
}
/**
* 根据模板生成内容
*
* @param templateName 模板名称
* @param dataMap 数据
* @return 生成得预览路径
* @throws Exception 异常
*/
public String gen(String templateName, Map<String, Object> dataMap) throws Exception {
OutputStream os = null;
try {
File outFile = new File(Consts.uploadAbsDir());
if (!outFile.exists()) {
outFile.mkdirs();
}
String templatePath = Consts.getTemplatePath();
String abTemplatePath = templatePath + File.separator + templateName + ".docx";
//判断模板是否存在
File file = new File(abTemplatePath);
if (!file.exists()) {
throw new KkFileException("请先上传模板!");
}
XWPFDocument xwpfDocument = WordExportUtil.exportWord07(abTemplatePath, dataMap);
//如果是签收单,则需要合并单元格
if (Consts.RECEIPT_FORM.equals(templateName)){
List<Object> invoiceResList = (List<Object>) MapUtils.getObject(dataMap, "invoiceResList");
mergeCell(xwpfDocument,0,7,7+invoiceResList.size()-1,Arrays.asList(5,6));
}
if (Consts.RECEIPT_INVOICE.equals(templateName)){
List<Object> invoiceResList = (List<Object>) MapUtils.getObject(dataMap, "invoiceResList");
mergeCell(xwpfDocument,0,7,7+invoiceResList.size()-1,Arrays.asList(5,6));
}
String docxFile = "/"+ UUID.randomUUID().toString().replace("-", "") + ".docx";
//通过填参 生产文件 并放到 upload 文件夹中
String path = Consts.uploadAbsDir();
String pathFile = path + docxFile;
os = new FileOutputStream(pathFile);
xwpfDocument.write(os);
log.info("文件路径:{}", kkfileConfig.getLocalfileUrl() + File.separator + Consts.UPLOAD_PATH_NAME + docxFile);
String previewUrl = WebUtils.getBaseUrl() + "onlinePreview?url=" +
URLEncoder.encode(Base64.encodeBase64String((kkfileConfig.getLocalfileUrl() + File.separator + Consts.UPLOAD_PATH_NAME + docxFile).getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8.name());
return previewUrl;
} finally {
if (os != null) {
os.close();
}
}
}
/**
* 合并单元格
* @param xwpfDocument 文档对象
* @param tableIndex 表格索引
* @param beginRowIndex 开始行索引
* @param endRowIndex 结束行索引
* @param collIndexs 合并列索引
*/
public static void mergeCell(XWPFDocument xwpfDocument,int tableIndex,int beginRowIndex,int endRowIndex,List<Integer> collIndexs){
//获取文档中指定的表格对象
XWPFTable table = xwpfDocument.getTableArray(tableIndex);
if (beginRowIndex == endRowIndex || beginRowIndex > endRowIndex){
return;
}
//合并单元格的第一个单元格
CTVMerge startMerge = CTVMerge.Factory.newInstance();
startMerge.setVal(STMerge.RESTART);
//合并行单元格之后的单元格
CTVMerge endMerge = CTVMerge.Factory.newInstance();
endMerge.setVal(STMerge.CONTINUE);
for (Integer collIndex : collIndexs){
table.getRow(beginRowIndex).getCell(collIndex).getCTTc().getTcPr().setVMerge(startMerge);
for (int i = beginRowIndex + 1; i <= endRowIndex; i++){
table.getRow(i).getCell(collIndex).getCTTc().getTcPr().setVMerge(endMerge);
}
}
}
/**
* 获取扩展名
*
* @param fileName 文件名
* @return 扩展名
*/
public static final String getExtension(String fileName) {
return FilenameUtils.getExtension(fileName);
}
/**
* 获取绝对路径
*
* @param uploadDir 上传得目录
* @param fileName 文件
* @return 获取文件绝对路径
* @throws IOException 异常
*/
public File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
File desc = new File(uploadDir + File.separator + fileName);
if (!desc.exists()) {
if (!desc.getParentFile().exists()) {
desc.getParentFile().mkdirs();
}
}
return desc;
}
public File download(String templateName, Map<String, Object> dataMap) throws Exception {
OutputStream os = null;
try {
File outFile = new File(Consts.uploadAbsDir());
if (!outFile.exists()) {
outFile.mkdirs();
}
String templatePath = Consts.getTemplatePath();
String abTemplatePath = templatePath + File.separator + templateName + ".docx";
//判断模板是否存在
File file = new File(abTemplatePath);
if(!file.exists()){
throw new KkFileException("请先上传模板!");
}
XWPFDocument xwpfDocument = WordExportUtil.exportWord07(abTemplatePath, dataMap);
//如果是签收单,则需要合并单元格
if (Consts.RECEIPT_FORM.equals(templateName)){
List<Object> invoiceResList = (List<Object>) MapUtils.getObject(dataMap, "invoiceResList");
mergeCell(xwpfDocument,0,6,6+invoiceResList.size()-1,Arrays.asList(4,5));
}
String docxFile = "/"+ UUID.randomUUID().toString().replace("-", "") + ".docx";
String pdfName = "/"+ UUID.randomUUID().toString().replace("-", "") + ".pdf";
//通过填参 生产文件 并放到 upload 文件夹中
String path = Consts.uploadAbsDir();
String pathFile = path + docxFile;
os = new FileOutputStream(pathFile);
xwpfDocument.write(os);
String outFilePath = Consts.uploadAbsDir()+ File.separator+ pdfName;
officeToPdfService.openOfficeToPDF(pathFile, outFilePath);
//返回pdf
return new File(outFilePath);
//返回word
//return new File(pathFile);
} finally {
if (os != null) {
os.close();
}
}
}
}