diff --git a/src/main/java/com/example/survey/service/impl/RecordServiceImpl.java b/src/main/java/com/example/survey/service/impl/RecordServiceImpl.java index 40bb492..387626e 100644 --- a/src/main/java/com/example/survey/service/impl/RecordServiceImpl.java +++ b/src/main/java/com/example/survey/service/impl/RecordServiceImpl.java @@ -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"; diff --git a/src/main/java/com/example/survey/util/CaseQuestionnaireUtil.java b/src/main/java/com/example/survey/util/CaseQuestionnaireUtil.java new file mode 100644 index 0000000..b4c6d00 --- /dev/null +++ b/src/main/java/com/example/survey/util/CaseQuestionnaireUtil.java @@ -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 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(); + } + +} diff --git a/src/main/java/com/example/survey/util/WordUtil.java b/src/main/java/com/example/survey/util/WordUtil.java index 5f5a649..f19693c 100644 --- a/src/main/java/com/example/survey/util/WordUtil.java +++ b/src/main/java/com/example/survey/util/WordUtil.java @@ -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 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 tables = document.getTables(); HashMap runs = new HashMap<>(); @@ -107,7 +112,187 @@ public class WordUtil { FileUtils.forceDelete(temp); } - + public void export2QuestionnaireWord() + throws FileNotFoundException, IOException, NoSuchMethodException, SecurityException { + List 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 tables = document.getTables(); + HashMap runs = new HashMap<>(); + for (XWPFTable table : tables) { + // 遍历表格 + List rows = table.getRows(); + for (int i = 0; i < rows.size(); i++) { + XWPFTableRow row = table.getRow(i); + List 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 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 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 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 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]; diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 7b9c95f..6b13823 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -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 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 050e5fa..cb33fcf 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: profiles: - active: prod + active: dev servlet: multipart: max-request-size: 200MB