| package com.zy.crm.manager.utils; | 
|   | 
| 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 java.io.*; | 
| import java.text.DecimalFormat; | 
| import java.text.NumberFormat; | 
| import java.util.ArrayList; | 
| 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); | 
|     } | 
|   | 
|     /** | 
|      * 处理段落中文本,替换文本中定义的变量; | 
|      * @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); | 
|     } | 
|   | 
| } |