package com.zy.crm.manager.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; 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 org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController public class WordController { @GetMapping("/generateWord") public ResponseEntity generateWord() throws IOException { // 读取 Word 模板文件 String fileName = this.getClass().getClassLoader().getResource("word1.docx").getPath();//获取文件路径 File file = new File(fileName); FileInputStream inputStream = new FileInputStream(file); XWPFDocument document = new XWPFDocument(inputStream); insertTab("${table}", document); HashMap map = new HashMap<>(); map.put("${table}", ""); map.put("${name}", "张三"); processParagraphs(document.getParagraphs(), 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); } /** * 处理段落中文本,替换文本中定义的变量; * @param paragraphList 段落列表 * @param param 需要替换的变量及变量值 * @param doc 需要替换的DOC */ public static void processParagraphs(List paragraphList, HashMap param, XWPFDocument doc) { if (paragraphList != null && paragraphList.size() > 0) { for (XWPFParagraph paragraph : paragraphList) { List runs = paragraph.getRuns(); for (XWPFRun run : runs) { String text = run.getText(0); if (text != null) { boolean isSetText = false; for (Map.Entry entry : param.entrySet()) { String key = entry.getKey(); if (text.indexOf(key) != -1) { isSetText = true; Object value = entry.getValue(); if (value instanceof String) {// 文本替换 text = text.replace(key, value.toString()); } } } if (isSetText) { run.setText(text, 0); } } } } } } /** * 在定位的位置插入表格 */ public static void insertTab(String key, XWPFDocument doc2) { List paragraphList = doc2.getParagraphs(); if (paragraphList != null && paragraphList.size() > 0) { for (XWPFParagraph paragraph : paragraphList) { List 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 = doc2.insertNewTbl(cursor);// ---这个是关键 String test = "[\n" + " [\"序号\",\"品名\",\"数量\",\"单位\",\"单价(元)\",\"合计(元)\",\"备注\"],\n" + " [\"1\",\"自动化立体仓库设备\",\"1\",\"套\",\"130000\",\"130000\",\"备注\"],\n" + " [\"合计(大写金额):\",\"\",\"\",\"\",\"合计:\",\"\",\"\"]\n" + "]"; JSONArray row = JSON.parseArray(test); ArrayList> list = new ArrayList<>(); for (Object o : row) { ArrayList arrayList = new ArrayList<>(); JSONArray objects = JSON.parseArray(o.toString()); for (Object object : objects) { arrayList.add(object.toString()); } list.add(arrayList); } int rows = list.size(); int cols = list.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(list.get(i).get(j)); }else { XWPFTableCell cell = tableRow.getCell(j); if (cell == null) { tableRow.addNewTableCell().setText(list.get(i).get(j)); }else { cell.setText(list.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); } } } } } } }