record export to word

This commit is contained in:
戴凡 2021-10-13 16:26:54 +08:00
parent 50a7e3f3a5
commit 068b470886
5 changed files with 478 additions and 21 deletions

View File

@ -10,6 +10,7 @@ import com.example.survey.enumeration.RecordStateEnum;
import com.example.survey.enumeration.ResultEnum;
import com.example.survey.exception.*;
import com.example.survey.service.RecordService;
import com.example.survey.util.CaseQuestionnaireUtil;
import com.example.survey.util.DownloadUtil;
import com.example.survey.util.ThreadWordUtil;
import com.example.survey.util.WordUtil;
@ -61,6 +62,9 @@ public class RecordServiceImpl implements RecordService {
@Autowired
private ThreadWordUtil threadWordUtil;
@Autowired
private CaseQuestionnaireUtil questionnaireWordUtil;
@Override
public void reviewRecord(ReviewRecordDTO reviewRecordDTO) {
if (!userDao.existUser(reviewRecordDTO.getReviewerPhone())) {
@ -266,19 +270,24 @@ public class RecordServiceImpl implements RecordService {
@Override
public boolean record2word(String uuid) {
Record record = recordDao.getRecord(uuid);
if(!record.getMetaDataType().equals(MetaDataTypeEnum.REPORT_TEMP.getValue())) {
if(record.getMetaDataType().equals(MetaDataTypeEnum.REPORT_TEMP.getValue())) {
// throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
threadWordUtil.setRecord(record);
threadWordUtil.setThreadName(record.getUuid() + ":" + String.valueOf(System.currentTimeMillis()));
threadWordUtil.start();
}
else if(record.getMetaDataType().equals(MetaDataTypeEnum.RECORD_TEMP.getValue())){
questionnaireWordUtil.setRecord(record);
questionnaireWordUtil.setThreadName(record.getUuid() + ":" + String.valueOf(System.currentTimeMillis()));
questionnaireWordUtil.start();
}
else {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
if(record.getState().equals(RecordStateEnum.REVIEWED.getValue())) {
return true;
}
threadWordUtil.setRecord(record);
threadWordUtil.setThreadName(record.getUuid() + ":" + String.valueOf(System.currentTimeMillis()));
// ThreadWordUtil wordUtil = new ThreadWordUtil();
// wordUtil.setRecord(record);
// wordUtil.setThreadName(record.getUuid() + ":" + String.valueOf(System.currentTimeMillis()));
threadWordUtil.start();
return true;
}
@ -318,13 +327,13 @@ public class RecordServiceImpl implements RecordService {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
if(!record.getMetaDataType().equals(MetaDataTypeEnum.REPORT_TEMP.getValue())) {
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
// if(!record.getMetaDataType().equals(MetaDataTypeEnum.REPORT_TEMP.getValue())) {
// throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
// }
if(!record.getState().equals(RecordStateEnum.REVIEWED.getValue())){
throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
}
// if(!record.getState().equals(RecordStateEnum.REVIEWED.getValue())){
// throw new RecordException(ResultEnum.NOT_EXIST_RECORD);
// }
String path = this.report + record.getUuid() + ".docx";

View File

@ -0,0 +1,73 @@
package com.example.survey.util;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import com.example.survey.dao.RecordDao;
import com.example.survey.entity.Record;
import com.example.survey.enumeration.RecordStateEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import lombok.Data;
@Data
@Component
public class CaseQuestionnaireUtil implements Runnable {
public static void main() {
CaseQuestionnaireUtil c = new CaseQuestionnaireUtil();
// Record record =
// c.setRecord(record);
c.start();
}
private Record record;
private Thread t;
private String threadName;
@Value("${file.path}")
private String path;
@Value("${file.report}")
private String report;
@Value("${file.template}")
private String template;
@Autowired
private RecordDao recordDao;
@Override
public void run() {
if (record != null) {
System.out.println("=========Start Export============");
String templatePath = this.template + record.getMetaData().getName() + ".docx";
String outputPath = this.report + record.getUuid() + ".docx";
try {
Map<String, Object> values = record.getValues();
if (!values.containsKey("调查人"))
values.put("调查人", record.getOperationList().get(0).getUser().getUsername());
if (!values.containsKey("调查日期"))
values.put("调查日期", new SimpleDateFormat("yyyy年MM月dd日").format(new java.util.Date()));
WordUtil wordUtil = new WordUtil(values, templatePath, outputPath);
wordUtil.export2QuestionnaireWord();
record.setState(RecordStateEnum.REVIEWED.getValue());
recordDao.saveRecord(record);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void start() {
t = new Thread(this, threadName);
t.start();
}
}

View File

@ -1,18 +1,22 @@
package com.example.survey.util;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.PositionInParagraph;
import org.apache.poi.xwpf.usermodel.TextSegment;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.poi.xwpf.usermodel.XWPFRun.FontCharRange;
import org.apache.xmlbeans.XmlCursor;
import org.graalvm.compiler.word.Word;
import org.springframework.stereotype.Component;
import javax.lang.model.util.ElementScanner6;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
@ -22,8 +26,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
/**
* @author Pope
@ -39,7 +45,7 @@ public class WordUtil {
public WordUtil(Map<String, Object> values, String templatePath, String outputPath)
throws FileNotFoundException, IOException, NoSuchMethodException, SecurityException {
temp = new File(UUID.randomUUID() + "t.docx");
temp = new File(UUID.randomUUID() + "t.docx");
this.outputPath = outputPath;
FileUtils.copyFile(new File(templatePath), temp);
OPCPackage pack = POIXMLDocument.openPackage(temp.getAbsolutePath());
@ -53,8 +59,7 @@ public class WordUtil {
key2methods.put("@", getClass().getDeclaredMethod("processTable", XWPFTableCell.class, String.class));
}
public void export2word()
throws FileNotFoundException, IOException, NoSuchMethodException, SecurityException {
public void export2word() throws FileNotFoundException, IOException, NoSuchMethodException, SecurityException {
List<XWPFTable> tables = document.getTables();
HashMap<String, XWPFTableCell> runs = new HashMap<>();
@ -107,7 +112,187 @@ public class WordUtil {
FileUtils.forceDelete(temp);
}
public void export2QuestionnaireWord()
throws FileNotFoundException, IOException, NoSuchMethodException, SecurityException {
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
String paraText = paragraph.getParagraphText();
int startIndex = paraText.indexOf("&{");
while (startIndex != -1) {
int endIndex = paraText.indexOf("}", startIndex + 2);
String trueKey = paraText.substring(startIndex + 2, endIndex);
String key = "&{" + trueKey + "}";
if (values.containsKey(trueKey)) {
Object valueObj = values.get(trueKey);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
if (valueObj instanceof ArrayList<?>) {
for (Object o : (List<?>) valueObj) {
String value = o.toString();
try {
Date date = dateFormat.parse(value);
replaceInParagragh(paragraph, key, new SimpleDateFormat("yyyy年MM月dd日").format(date));
} catch (Exception e) {
replaceInParagragh(paragraph, key, value);
}
break;
}
} else if (valueObj.getClass().isArray()) {
Object[] arr = (Object[]) valueObj;
try {
Date date = dateFormat.parse(arr[0].toString());
replaceInParagragh(paragraph, key, new SimpleDateFormat("yyyy年MM月dd日").format(date));
} catch (Exception e) {
replaceInParagragh(paragraph, key, arr[0].toString());
}
} else {
String value = valueObj.toString();
try {
Date date = dateFormat.parse(value);
replaceInParagragh(paragraph, key, new SimpleDateFormat("yyyy年MM月dd日").format(date));
} catch (Exception e) {
replaceInParagragh(paragraph, key, value);
}
}
// replaceInParagragh(paragraph, key, value);
} else {
replaceInParagragh(paragraph, key, " ");
}
startIndex = paraText.indexOf("&{", endIndex + 1);
}
startIndex = paraText.indexOf("*{");
while (startIndex != -1) {
int endIndex = paraText.indexOf("}", startIndex + 2);
String trueKey = paraText.substring(startIndex + 2, endIndex);
String key = "*{" + trueKey + "}";
if (values.containsKey(trueKey)) {
TextSegment textSeg = paragraph.searchText(key, new PositionInParagraph());
int startPosRun = textSeg.getBeginRun();
Object valueObj = values.get(trueKey);
if (valueObj instanceof ArrayList<?>) {
for (Object o : (List<?>) valueObj) {
String oldText = o.toString() + "";
TextSegment tSegment = paragraph.searchText(oldText,
new PositionInParagraph(startPosRun, 0, 0));
if (tSegment != null) {
String newText = o.toString();
replaceInParagragh(paragraph, tSegment, oldText, newText);
} else {
oldText = "" + o.toString();
tSegment = paragraph.searchText(oldText, new PositionInParagraph(startPosRun, 0, 0));
if (tSegment != null) {
String newText = o.toString();
replaceInParagragh(paragraph, tSegment, oldText, newText);
}
}
}
} else if (valueObj.getClass().isArray()) {
Object[] arr = (Object[]) valueObj;
for (int i = 0; i < arr.length; i++) {
String oldText = arr[i] + "";
TextSegment tSegment = paragraph.searchText(oldText,
new PositionInParagraph(startPosRun, 0, 0));
if (tSegment != null) {
String newText = arr[i].toString();
replaceInParagragh(paragraph, tSegment, oldText, newText);
} else {
oldText = "" + arr[i];
tSegment = paragraph.searchText(oldText, new PositionInParagraph(startPosRun, 0, 0));
if (tSegment != null) {
String newText = arr[i].toString();
replaceInParagragh(paragraph, tSegment, oldText, newText);
}
}
}
} else {
String oldText = valueObj.toString() + "";
TextSegment tSegment = paragraph.searchText(oldText,
new PositionInParagraph(startPosRun, 0, 0));
if (tSegment != null) {
String newText = valueObj.toString();
replaceInParagragh(paragraph, tSegment, oldText, newText);
} else {
oldText = "" + valueObj.toString();
tSegment = paragraph.searchText(oldText, new PositionInParagraph(startPosRun, 0, 0));
if (tSegment != null) {
String newText = valueObj.toString();
replaceInParagragh(paragraph, tSegment, oldText, newText);
}
}
}
}
startIndex = paraText.indexOf("*{", endIndex + 1);
// replaceInParagragh(paragraph, key, trueKey);
if (trueKey.lastIndexOf("_") != -1) {
Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
if (trueKey.substring(trueKey.lastIndexOf("_") + 1).length() > 0
&& pattern.matcher(trueKey.substring(trueKey.lastIndexOf("_") + 1)).matches()) {
replaceInParagragh(paragraph, key, trueKey.substring(0, trueKey.lastIndexOf("_")));
}
} else {
switch (trueKey) {
case "单位级别":
replaceInParagragh(paragraph, key, "");
break;
default:
replaceInParagragh(paragraph, key, trueKey);
break;
}
}
}
}
List<XWPFTable> tables = document.getTables();
HashMap<String, XWPFTableCell> runs = new HashMap<>();
for (XWPFTable table : tables) {
// 遍历表格
List<XWPFTableRow> rows = table.getRows();
for (int i = 0; i < rows.size(); i++) {
XWPFTableRow row = table.getRow(i);
List<XWPFTableCell> cells = row.getTableCells();
for (int j = 0; j < cells.size(); j++) {
XWPFTableCell cell = cells.get(j);
String key = cell.getText();
if (key.length() == 0) {
continue;
}
String keyHead = key.substring(0, 1);
String trueKey = key.substring(1);
if (key2methods.containsKey(keyHead)) {
cell.removeParagraph(0);
} else {
continue;
}
if (values.containsKey(trueKey)) {
runs.put(key, cell);
} else {
cell.setText("");
}
}
}
}
for (Entry<String, XWPFTableCell> entry : runs.entrySet()) {
String key = entry.getKey();
XWPFTableCell cell = entry.getValue();
Method method = key2methods.get(key.subSequence(0, 1));
String trueKey = key.substring(1);
try {
method.invoke(this, cell, values.get(trueKey));
} catch (Exception e) {
e.printStackTrace();
cell.setText("");
}
}
OutputStream outputStream = new FileOutputStream(outputPath);
document.write(outputStream);
outputStream.close();
document.close();
FileUtils.forceDelete(temp);
}
private void processText(XWPFTableCell cell, String msg) {
// 执行\n换行
if (msg == null) {
@ -121,7 +306,7 @@ public class WordUtil {
List<XWPFParagraph> pglist = cell.getParagraphs();
for (int pi = 0; pi < pglist.size(); pi++) {
XWPFRun run = pglist.get(pi).createRun();
if(pi >= st.length){
if (pi >= st.length) {
System.out.println("ERROR!!!!!!!!!!!");
continue;
}
@ -130,6 +315,196 @@ public class WordUtil {
}
private void replaceInParagragh(XWPFParagraph paragraph, String oldText, String newText) {
List<XWPFRun> runs = paragraph.getRuns();
TextSegment tSegment = paragraph.searchText(oldText, new PositionInParagraph());
if (tSegment != null) {
int beginRun = tSegment.getBeginRun();
int endRun = tSegment.getEndRun();
if (beginRun == endRun) {
XWPFRun run = runs.get(beginRun);
String runText = run.getText(0);
String replaced = runText.replace(oldText, newText);
run.setText(replaced, 0);
} else {
StringBuilder b = new StringBuilder();
for (int runPos = beginRun; runPos <= endRun; runPos++) {
XWPFRun run = runs.get(runPos);
b.append(run.getText(0));
}
String connectedRuns = b.toString();
String replaced = connectedRuns.replace(oldText, newText);
XWPFRun partOne = runs.get(beginRun);
partOne.setText(replaced, 0);
for (int runPos = beginRun + 1; runPos <= endRun; runPos++) {
XWPFRun partNext = runs.get(runPos);
partNext.setText("", 0);
}
}
}
}
private void replaceInParagragh(XWPFParagraph paragraph, TextSegment tSegment, String oldText, String newText) {
List<XWPFRun> runs = paragraph.getRuns();
int beginRun = tSegment.getBeginRun();
int endRun = tSegment.getEndRun();
if (beginRun == endRun) {
XWPFRun run = runs.get(beginRun);
String runText = run.getText(0);
String replaced = runText.replace(oldText, newText);
int textIndex = replaced.indexOf(newText);
// run.setText(replaced, 0);
String fontFamily = run.getFontFamily();
int fontSize = run.getFontSize();
if (oldText.startsWith("")) {
XWPFRun replacedRun = null;
String redundantText = replaced.substring(0, textIndex);
if (redundantText.length() > 0) {
replacedRun = paragraph.insertNewRun(beginRun);
if (fontFamily != null) {
replacedRun.setFontFamily(fontFamily);
}
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText(redundantText, 0);
beginRun++;
}
replacedRun = paragraph.insertNewRun(beginRun);
replacedRun.setFontFamily("MS Gothic");
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText("\u2611", 0);
replacedRun = paragraph.insertNewRun(beginRun + 1);
if (fontFamily != null) {
replacedRun.setFontFamily(fontFamily);
}
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText(replaced.substring(textIndex), 0);
} else {
XWPFRun replacedRun = null;
String redundantText = replaced.substring(0, textIndex + newText.length());
replacedRun = paragraph.insertNewRun(beginRun);
if (fontFamily != null) {
replacedRun.setFontFamily(fontFamily);
}
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText(redundantText, 0);
replacedRun = paragraph.insertNewRun(beginRun + 1);
replacedRun.setFontFamily("MS Gothic");
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText("\u2611", 0);
redundantText = replaced.substring(textIndex + newText.length());
if (redundantText.length() > 0) {
replacedRun = paragraph.insertNewRun(beginRun + 2);
if (fontFamily != null) {
replacedRun.setFontFamily(fontFamily);
}
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText(redundantText, 0);
beginRun++;
}
}
} else {
StringBuilder b = new StringBuilder();
for (int runPos = beginRun; runPos <= endRun; runPos++) {
XWPFRun run = runs.get(runPos);
b.append(run.getText(0));
}
String connectedRuns = b.toString();
String replaced = connectedRuns.replace(oldText, newText);
XWPFRun partOne = runs.get(beginRun);
partOne.setText(replaced, 0);
for (int runPos = beginRun + 1; runPos <= endRun; runPos++) {
XWPFRun partNext = runs.get(runPos);
partNext.setText("", 0);
}
int textIndex = replaced.indexOf(newText);
String fontFamily = partOne.getFontFamily();
int fontSize = partOne.getFontSize();
if (oldText.startsWith("")) {
XWPFRun replacedRun = null;
String redundantText = replaced.substring(0, textIndex);
if (redundantText.length() > 0) {
replacedRun = paragraph.insertNewRun(beginRun);
if (fontFamily != null) {
replacedRun.setFontFamily(fontFamily);
}
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText(redundantText, 0);
beginRun++;
}
replacedRun = paragraph.insertNewRun(beginRun);
replacedRun.setFontFamily("MS Gothic");
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText("\u2611", 0);
replacedRun = paragraph.insertNewRun(beginRun + 1);
if (fontFamily != null) {
replacedRun.setFontFamily(fontFamily);
}
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText(replaced.substring(textIndex), 0);
} else {
XWPFRun replacedRun = null;
String redundantText = replaced.substring(0, textIndex + newText.length());
replacedRun = paragraph.insertNewRun(beginRun);
if (fontFamily != null) {
replacedRun.setFontFamily(fontFamily);
}
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText(redundantText, 0);
replacedRun = paragraph.insertNewRun(beginRun + 1);
replacedRun.setFontFamily("MS Gothic");
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText("\u2611", 0);
redundantText = replaced.substring(textIndex + newText.length());
if (redundantText.length() > 0) {
replacedRun = paragraph.insertNewRun(beginRun + 2);
if (fontFamily != null) {
replacedRun.setFontFamily(fontFamily);
}
if (fontSize != -1) {
replacedRun.setFontSize(fontSize);
}
replacedRun.setText(redundantText, 0);
beginRun++;
}
}
}
paragraph.removeRun(beginRun + 2);
}
private void processImage(XWPFTableCell cell, String imgInfo) {
String[] infos = imgInfo.split(":");
String imgPath = infos[0];

View File

@ -6,7 +6,7 @@ spring:
auto-index-creation: true
host: 8.136.133.77
port: 27017
database: dev
database: survey
username: cveo
password: cveo123456
authentication-database: admin

View File

@ -1,6 +1,6 @@
spring:
profiles:
active: prod
active: dev
servlet:
multipart:
max-request-size: 200MB