package com.zy.crm.manager.utils;
|
|
import com.documents4j.api.DocumentType;
|
import com.documents4j.api.IConverter;
|
import com.documents4j.job.LocalConverter;
|
import org.apache.poi.xwpf.usermodel.*;
|
import org.apache.xmlbeans.XmlCursor;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
|
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.MediaType;
|
import org.springframework.http.ResponseEntity;
|
|
import java.io.*;
|
import java.text.DecimalFormat;
|
import java.text.NumberFormat;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
|
//Word操作工具类
|
public class WordUtils {
|
|
//生成word合同
|
public static ResponseEntity<InputStreamResource> generate(String fileName, HashMap<String, Object> map, List<List<String>> tabParam) throws IOException {
|
// 读取 Word 模板文件
|
File file = new File(fileName);
|
FileInputStream inputStream = new FileInputStream(file);
|
XWPFDocument document = new XWPFDocument(inputStream);
|
|
insertTab("{{table}}", document, tabParam);
|
|
map.put("{{table}}", "");
|
processParagraphs(map, document);
|
|
// 将文档写入输出流
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
document.write(outputStream);
|
outputStream.close();
|
|
// 创建响应实体,将输出流作为文件内容返回
|
HttpHeaders headers = new HttpHeaders();
|
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
headers.setContentDispositionFormData("attachment", "output.docx");
|
InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(outputStream.toByteArray()));
|
return ResponseEntity.ok()
|
.headers(headers)
|
.body(resource);
|
}
|
|
/*
|
* word转PDF
|
* */
|
public static void documents4jWordToPdf(String sourcePath, String targetPath) {
|
File inputWord = new File(sourcePath);
|
File outputFile = new File(targetPath);
|
try {
|
InputStream docxInputStream = new FileInputStream(inputWord);
|
OutputStream outputStream = new FileOutputStream(outputFile);
|
IConverter converter = LocalConverter.builder().build();
|
boolean execute = converter.convert(docxInputStream)
|
.as(DocumentType.DOCX)
|
.to(outputStream)
|
.as(DocumentType.PDF).schedule().get();
|
outputStream.close();
|
docxInputStream.close();
|
|
System.out.println("转换完毕 targetPath = "+outputFile.getAbsolutePath());
|
converter.shutDown();
|
return;
|
} catch (Exception e) {
|
System.out.println("[documents4J] word转pdf失败:"+e.toString());
|
}
|
}
|
|
/**
|
* 处理段落中文本,替换文本中定义的变量;
|
* @param param 需要替换的变量及变量值
|
* @param document 需要替换的DOC
|
*/
|
public static void processParagraphs(HashMap<String, Object> param, XWPFDocument document) {
|
// 遍历所有段落
|
for (XWPFParagraph paragraph : document.getParagraphs()) {
|
for (Map.Entry<String, Object> entry : param.entrySet()) {
|
String key = entry.getKey();
|
String value = entry.getValue().toString();
|
// 替换段落文本
|
replaceTextInParagraph(paragraph, key, value);
|
}
|
}
|
|
// 遍历所有表格
|
for (XWPFTable table : document.getTables()) {
|
// 遍历表格中的每个单元格
|
for (XWPFTableRow row : table.getRows()) {
|
for (XWPFTableCell cell : row.getTableCells()) {
|
for (Map.Entry<String, Object> entry : param.entrySet()) {
|
String key = entry.getKey();
|
String value = entry.getValue().toString();
|
// 替换表格单元格的文本
|
replaceTextInParagraph(cell.getParagraphs().get(0), key, value);
|
}
|
}
|
}
|
}
|
}
|
|
private static void replaceTextInParagraph(XWPFParagraph paragraph, String searchString, String replacementString) {
|
for (XWPFRun run : paragraph.getRuns()) {
|
// 获取段落中的文本
|
String text = run.getText(0);
|
if (text != null && text.contains(searchString)) {
|
// 使用正则表达式进行替换
|
Pattern pattern = Pattern.compile(Pattern.quote(searchString));
|
Matcher matcher = pattern.matcher(text);
|
if (matcher.find()) {
|
String replacedText = matcher.replaceAll(replacementString);
|
// 替换文本
|
run.setText(replacedText, 0);
|
}
|
}
|
}
|
}
|
|
/**
|
* 在定位的位置插入表格
|
*/
|
public static void insertTab(String key, XWPFDocument document, List<List<String>> param) {
|
List<XWPFParagraph> paragraphList = document.getParagraphs();
|
if (paragraphList != null && paragraphList.size() > 0) {
|
for (XWPFParagraph paragraph : paragraphList) {
|
List<XWPFRun> runs = paragraph.getRuns();
|
for (XWPFRun run : runs) {
|
String text = run.getText(0);
|
if (text != null) {
|
if (text.indexOf(key) >= 0) {
|
XmlCursor cursor = paragraph.getCTP().newCursor();
|
XWPFTable tableOne = document.insertNewTbl(cursor);// ---这个是关键
|
// String test = "[\n" +
|
// " [\"序号\",\"品名\",\"数量\",\"单位\",\"单价(元)\",\"合计(元)\",\"备注\"],\n" +
|
// " [\"1\",\"自动化立体仓库设备\",\"1\",\"套\",\"130000\",\"130000\",\"备注\"],\n" +
|
// " [\"合计(大写金额):\",\"\",\"\",\"\",\"合计:\",\"\",\"\"]\n" +
|
// "]";
|
//
|
// JSONArray row = JSON.parseArray(test);
|
// ArrayList<List<String>> list = new ArrayList<>();
|
// for (Object o : row) {
|
// ArrayList<String> arrayList = new ArrayList<>();
|
// JSONArray objects = JSON.parseArray(o.toString());
|
// for (Object object : objects) {
|
// arrayList.add(object.toString());
|
// }
|
// list.add(arrayList);
|
// }
|
|
int rows = param.size();
|
int cols = param.get(0).size();
|
for (int i = 0; i < rows; i++) {
|
XWPFTableRow tableRow = null;
|
if (i == 0) {
|
tableRow = tableOne.getRow(i);
|
} else {
|
tableRow = tableOne.createRow();
|
}
|
|
for (int j = 0; j < cols; j++) {
|
if (i == 0 && j == 0) {
|
tableRow.getCell(j).setText(param.get(i).get(j));
|
} else {
|
XWPFTableCell cell = tableRow.getCell(j);
|
if (cell == null) {
|
tableRow.addNewTableCell().setText(param.get(i).get(j));
|
} else {
|
cell.setText(param.get(i).get(j));
|
}
|
}
|
}
|
}
|
|
//合并最后一行单元格
|
tableOne.getRow(rows - 1).getCell(0).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
|
tableOne.getRow(rows - 1).getCell(1).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
|
tableOne.getRow(rows - 1).getCell(2).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
|
tableOne.getRow(rows - 1).getCell(4).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
|
tableOne.getRow(rows - 1).getCell(5).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
public static String formatNumberForAccounting(double number) {
|
if (number == 0) {
|
return "0.00";
|
}
|
NumberFormat formatter = new DecimalFormat("#,###.00");
|
return formatter.format(number);
|
}
|
|
}
|