中扬CRM客户关系管理系统
LSH
2024-03-26 7e408b4de778506c1544fa8f34ff289dd8b8c8df
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
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);
    }
 
}