公司HDFS网盘下载word模板,实现对模板的数据填充和创建临时文件上传

 1  /**
 2      * 获取通报单模板,填充模板,并上传网盘返回fileId
 3      */
 4     private JSONObject getReport(String reportNo, String projectName, String notificationObject, String notificationReason, HttpServletRequest request) {
 5         JSONObject returnJson = new JSONObject();
 6 
 7         RestTemplate restTemplate = new RestTemplate();
 8         HttpHeaders httpHeaders = new HttpHeaders();
 9         HttpEntity httpEntity = new HttpEntity(httpHeaders);
10         InputStream in = null;
11         ByteArrayOutputStream out = new ByteArrayOutputStream();
12         //填充模板的数据
13         JSONObject params = new JSONObject();
14         JSONObject tableData = new JSONObject();
15         tableData.put("number", reportNo);
16         tableData.put("date", DateUtil.format(new Date(), "yyyy-MM-dd").toString());
17         tableData.put("title", projectName);
18         tableData.put("target", notificationObject);
19         tableData.put("reason", notificationReason);
20         params.put("tableData", tableData);
21 
22         String fileId = null;
23         FileOutputStream fos = null;
24         BufferedOutputStream bos = null;
25         File fi = null;
26         try {
27             ResponseEntity<byte[]> getTempResponse = restTemplate.exchange(netdiscIP + netdiscDownload + reportTempFileId, HttpMethod.GET, httpEntity, byte[].class);
28             ByteArrayInputStream inputStream = new ByteArrayInputStream(getTempResponse.getBody());
29             PoiWordUtils.execute(inputStream, out, params);
30             byte[] bytes = out.toByteArray();
31             HttpHeaders headers = new HttpHeaders();
32             //设置名字
33             String downloadName = "督查通报建议单.docx";
34             //解决chrome/firefox/ie浏览器压缩包名字含有中文时乱码的问题
35             String agent = request.getHeader("USER-AGENT");
36             if (agent.contains("MSIE") || agent.contains("Trident")) {
37                 downloadName = java.net.URLEncoder.encode(downloadName, StandardCharsets.UTF_8.toString());
38             } else {
39                 downloadName = new String(downloadName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
40             }
41             headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName=\"" + downloadName + "\"");
42             headers.add(HttpHeaders.CONNECTION, "close");
43 
44             //创建临时文件上传
45             String tempFileName = "督查通报建议单_" + System.currentTimeMillis();
46             fi = File.createTempFile(tempFileName, ".docx");
47             fos = new FileOutputStream(fi);
48             bos = new BufferedOutputStream(fos);
49             bos.write(bytes);
50 
51             //设置请求头
52             HttpHeaders requestHeaders = new HttpHeaders();
53             MediaType type = MediaType.parseMediaType("multipart/form-data");
54             requestHeaders.setContentType(type);
55             System.out.println(fi);
56             System.out.println(fi.getName());
57 
58             //设置请求体,注意是LinkedMultiValueMap
59             FileInputStream input = new FileInputStream(fi);
60             MultipartFile multipartFile = new MockMultipartFile("file", fi.getName(), "text/plain", IOUtils.toByteArray(input));
61             HttpClientResult result = HttpClientUtils.doPostFile(netdiscIP + netdiscUpload, multipartFile);
62             JSONObject object = JSONObject.parseObject(result.getContent());
63             if (object != null && object.getInteger("code") == 200) {
64                 fileId = object.getString("data");
65             }
66             returnJson.put("fileName",tempFileName + ".docx");
67             returnJson.put("fileId",fileId );
68         } catch (Exception e) {
69             throw new RuntimeException(e.getMessage());
70         } finally {
71             try {
72                 if (bos != null) {
73                     try {
74                         bos.close();
75                     } catch (IOException e1) {
76                         e1.printStackTrace();
77                     }
78                 }
79                 if (fos != null) {
80                     try {
81                         fos.close();
82                     } catch (IOException e1) {
83                         e1.printStackTrace();
84                     }
85                 }
86                 if (in != null) {
87                     in.close();
88                 }
89                 fi.delete();
90                 out.close();
91             } catch (IOException e) {
92                 throw new RuntimeException(e.getMessage());
93             }
94         }
95         return returnJson;
96     }
PoiWordUtils:
  1 @Slf4j
  2 public class PoiWordUtils {
  3 
  4     /**
  5      * 顿号
  6      */
  7     private static final String DUNHAO = "、";
  8 
  9     /**
 10      * 执行
 11      *
 12      * @param in     模板输入流
 13      * @param out    文件输出流
 14      * @param params params
 15      * @Author LIZHIQIANG
 16      * @Date Create in 2020/1/14 9:58
 17      */
 18     public static void execute(InputStream in, OutputStream out, JSONObject params) {
 19         try {
 20             XWPFDocument document = new XWPFDocument(in);
 21             //需要循环的段落${listRow}开头,暂定最多三个
 22             List<XWPFParagraph> targetParagraphs1 = new ArrayList<>();
 23             List<XWPFParagraph> targetParagraphs2 = new ArrayList<>();
 24             List<XWPFParagraph> targetParagraphs3 = new ArrayList<>();
 25             List<IBodyElement> bodyElements = document.getBodyElements();
 26             for (IBodyElement element : bodyElements) {
 27                 //文本段落对象
 28                 if (element instanceof XWPFParagraph) {
 29                     XWPFParagraph paragraph = (XWPFParagraph) element;
 30                     //段落内容
 31                     String paragraphText = paragraph.getParagraphText();
 32 
 33                     //空段落跳过
 34                     if (paragraphText.isEmpty()) {
 35                         continue;
 36                     }
 37                     //需要循环的段落
 38                     if (paragraphText.startsWith("${listRow1}")) {
 39                         targetParagraphs1.add(paragraph);
 40                         continue;
 41                     }
 42                     if (paragraphText.startsWith("${listRow2}")) {
 43                         targetParagraphs2.add(paragraph);
 44                         continue;
 45                     }
 46                     if (paragraphText.startsWith("${listRow3}")) {
 47                         targetParagraphs3.add(paragraph);
 48                         continue;
 49                     }
 50                     //处理普通段落
 51                     processParagraph(paragraph, params);
 52                 } else if (element instanceof XWPFTable) {
 53                     XWPFTable table = (XWPFTable) element;
 54                     List<XWPFTableRow> rows = table.getRows();
 55                     String tableDataString = params.getString("tableData");
 56                     JSONObject tableData = JSON.parseObject(tableDataString);
 57                     System.out.println(JSON.toJSONString(tableData,true));
 58                     if (tableData == null) {
 59                         continue;
 60                     }
 61                     //需要循环的tableRows
 62                     List<XWPFTableRow> targetTableRows = new ArrayList<>();
 63                     List<Integer> targetTableRowsPos = new ArrayList<>();
 64                     for (int i = 0; i < rows.size(); i++) {
 65                         XWPFTableRow row = rows.get(i);
 66                         List<XWPFTableCell> cells = row.getTableCells();
 67                         String firstParagraphText2 = cells.get(0).getParagraphs().get(0).getParagraphText();
 68                         String firstParagraphText = cells.get(0).getParagraphs().get(0).getText();
 69                         if (firstParagraphText.startsWith("${listTables")) {
 70                             targetTableRows.add(row);
 71                             targetTableRowsPos.add(i);
 72                             continue;
 73                         }
 74                         for (XWPFTableCell cell : cells) {
 75                             List<XWPFParagraph> paragraphs = cell.getParagraphs();
 76                             for (XWPFParagraph paragraph : paragraphs) {
 77                                 processParagraph(paragraph, tableData);
 78                             }
 79                         }
 80                     }
 81                     processTableRows(table, targetTableRows, targetTableRowsPos, tableData);
 82                 }
 83 
 84             }
 85             //处理循环段落
 86             processParagraphs(document, targetParagraphs1, params, "1");
 87             processParagraphs(document, targetParagraphs2, params, "2");
 88             processParagraphs(document, targetParagraphs3, params, "3");
 89             document.write(out);
 90 
 91         } catch (IOException e) {
 92             e.printStackTrace();
 93         }
 94     }
 95 
 96     /**
 97      * 处理普通段落
 98      *
 99      * @param paragraph paragraph
100      * @param params    params
101      * @Author LIZHIQIANG
102      * @Date Create in 2020/1/14 9:38
103      */
104     private static void processParagraph(XWPFParagraph paragraph, JSONObject params) {
105 
106         List<XWPFRun> runs = paragraph.getRuns();
107         //需要循环替换的单元
108         List<XWPFRun> targetRuns1 = new ArrayList<>();
109         List<XWPFRun> targetRuns2 = new ArrayList<>();
110         List<XWPFRun> targetRuns3 = new ArrayList<>();
111         for (XWPFRun run : runs) {
112             String runKey = run.text();
113             System.out.println(runKey);
114             if (!runKey.startsWith("${") || !runKey.endsWith("}")) {
115                 continue;
116             }
117             if ("${#}".equals(runKey)) {
118                 run.setText("", 0);
119                 continue;
120             }
121             if ("${listTables1}".equals(runKey)) {
122                 run.setText("", 0);
123                 continue;
124             }
125             if (runKey.startsWith("${listRow")) {
126                 run.setText("", 0);
127                 continue;
128             }
129             //添加需要循环的单元
130             if (runKey.startsWith("${listRuns1")) {
131                 targetRuns1.add(run);
132                 continue;
133             }
134             if (runKey.startsWith("${listRuns2")) {
135                 targetRuns2.add(run);
136                 continue;
137             }
138             if (runKey.startsWith("${listRuns3")) {
139                 targetRuns3.add(run);
140                 continue;
141             }
142             String key = runKey.replace("${", "").replace("}", "");
143             String value = params.getString(key);
144             if (!StringUtils.isEmpty(value)) {
145                 run.setText(value, 0);
146             } else {
147                 run.setText("", 0);
148                 log.warn("处理普通段落单元失败:{},找不到替换数据", runKey);
149             }
150         }
151         //处理需要循环的单元
152         processRuns(paragraph, targetRuns1, params, "1");
153         processRuns(paragraph, targetRuns2, params, "2");
154         processRuns(paragraph, targetRuns3, params, "3");
155     }
156 
157     /**
158      * 处理需要循环的单元
159      *
160      * @param paragraph  paragraph
161      * @param targetRuns targetRuns
162      * @param params     params
163      * @return void
164      * @Author LIZHIQIANG
165      * @Date Create in 2020/3/1 18:06
166      */
167     private static void processRuns(XWPFParagraph paragraph, List<XWPFRun> targetRuns, JSONObject params, String sorting) {
168 
169         if (targetRuns.isEmpty() || params.isEmpty()) {
170             return;
171         }
172         //默认key
173         String defaultKey = "listRuns" + sorting;
174         JSONArray jsonArray = params.getJSONArray(defaultKey);
175         //循环需要替换的数据
176         for (int i = 0; i < jsonArray.size(); i++) {
177             Object data = jsonArray.get(i);
178             //参数 一次循环的参数
179             JSONObject param = JSON.parseObject(data.toString());
180             //循环需要替换的单元
181             for (XWPFRun run : targetRuns) {
182 
183                 String runKey = run.text();
184                 XWPFRun newRun = paragraph.createRun();
185                 CTRPr rPr = run.getCTR().getRPr();
186                 newRun.getCTR().setRPr(rPr);
187                 //处理顿号
188                 if (runKey.equals("${" + defaultKey + "DUNHAO}")) {
189                     if (i == jsonArray.size() - 1) {
190                         newRun.setText("", 0);
191                         continue;
192                     }
193                     newRun.setText(DUNHAO);
194                     continue;
195                 }
196                 String key = runKey.replace("${", "").replace("}", "");
197                 String value = param.getString(key);
198                 if (!StringUtils.isEmpty(value)) {
199                     newRun.setText(value);
200                 } else {
201                     log.warn("处理循环单元失败:{},找不到对应值", runKey);
202                     newRun.setText("", 0);
203                 }
204 
205             }
206         }
207         for (XWPFRun run : targetRuns) {
208             run.setText("", 0);
209         }
210 
211     }
212 
213     /**
214      * 处理循环段落(新增段落后删模板段落)
215      *
216      * @param document         document
217      * @param targetParagraphs targetParagraphs
218      * @param params           params
219      * @Author LIZHIQIANG
220      * @Date Create in 2020/1/14 9:38
221      */
222     private static void processParagraphs(XWPFDocument document, List<XWPFParagraph> targetParagraphs, JSONObject params, String sorting) {
223 
224         if (targetParagraphs.isEmpty() || params.isEmpty()) {
225             return;
226         }
227         String listKey = "listRow" + sorting;
228         JSONArray jsonArray = params.getJSONArray(listKey);
229         if (jsonArray == null) {
230             return;
231         }
232 
233         //document.insertNewParagraph(cursor) 插到这个光标前面 所以反转
234         Collections.reverse(targetParagraphs);
235         Collections.reverse(jsonArray);
236         //需要追加的此段落后 最后一个
237         XWPFParagraph lastParagraph = document.getParagraphArray(document.getPosOfParagraph(targetParagraphs.get(0)));
238         //循环需要替换的数据
239 //        for (int i = 0; i < jsonArray.size(); i++) {
240 //            Object data = jsonArray.get(i);
241 //            //参数 一次循环的参数
242 //            JSONObject param = JSON.parseObject(data.toString());
243 //            System.out.println(JSON.toJSONString(param,true));
244 //            for (XWPFParagraph paragraph : targetParagraphs) {
245 //                System.out.println("处理段落:"+paragraph.getText());
246 //                //根据光标插入段落
247 //                //需要追加的此段落光标后 最后一个
248 //                XmlCursor cursor = lastParagraph.getCTP().newCursor();
249 //                XWPFParagraph newPar = document.insertNewParagraph(cursor);
250 //
251 //                lastParagraph = newPar;
252 //                //重置光标 最后插入的光标是这个
253 //                //获取段落对象的样式的ppr标签
254 //                CTPPr pPr = paragraph.getCTP().getPPr();
255 //                newPar.getCTP().setPPr(pPr);
256 //                List<XWPFRun> runs = paragraph.getRuns();
257 //
258 //                //需要循环替换的单元
259 //                List<XWPFRun> targetRuns1 = new ArrayList<>();
260 //                List<XWPFRun> targetRuns2 = new ArrayList<>();
261 //                List<XWPFRun> targetRuns3 = new ArrayList<>();
262 //                for (XWPFRun run : runs) {
263 //                    String runKey = run.text();
264 //                    CTRPr rPr = run.getCTR().getRPr();
265 //                    XWPFRun newRun = newPar.createRun();
266 //                    newRun.getCTR().setRPr(rPr);
267 //                    if (!runKey.startsWith("${") || !runKey.endsWith("}")) {
268 //                        newRun.setText(runKey);
269 //                        continue;
270 //                    }
271 //                    //添加需要循环的单元
272 //                    if (runKey.startsWith("${listRuns1")) {
273 //                        targetRuns1.add(run);
274 //                        continue;
275 //                    }
276 //                    if (runKey.startsWith("${listRuns2")) {
277 //                        targetRuns2.add(run);
278 //                        continue;
279 //                    }
280 //                    if (runKey.startsWith("${listRuns3")) {
281 //                        targetRuns3.add(run);
282 //                        continue;
283 //                    }
284 //                    if (("${" + listKey + "}").equals(runKey)) {
285 //                        newRun.setText("");
286 //                        continue;
287 //                    }
288 //                    if ("${#}".equals(runKey)) {
289 //                        run.setText("", 0);
290 //                        continue;
291 //                    }
292 //                    String key = runKey.replace("${", "").replace("}", "");
293 //                    String value = param.getString(key);
294 //                    if (!StringUtils.isEmpty(value)) {
295 //                        newRun.setText(value);
296 ////                        System.out.println("处理单元:"+runKey+" > "+value);
297 //                        continue;
298 //                    } else {
299 //                        log.warn("处理循环模板段落单元失败:{},找不到对应值", runKey);
300 //                    }
301 //                    newRun.setText(runKey);
302 //                }
303 //                //===处理需要循环的单元
304 //                processRuns(newPar, targetRuns1, param, "1");
305 //                processRuns(newPar, targetRuns2, param, "2");
306 //                processRuns(newPar, targetRuns3, param, "3");
307 //
308 //            }
309 //        }
310         //删除模板集合段落
311         XmlCursor lastCursor = lastParagraph.getCTP().newCursor();
312         for (Object data : jsonArray) {
313             JSONObject param = JSON.parseObject(data.toString());
314             for (XWPFParagraph paragraph : targetParagraphs) {
315                 //根据光标插入段落
316                 XWPFParagraph newPar = document.insertNewParagraph(lastCursor);
317                 //重置光标 最后插入的光标是这个
318                 lastCursor = newPar.getCTP().newCursor();
319                 //复制段落
320                 copyParagraph(paragraph, newPar);
321                 //处理普通段落
322                 processParagraph(newPar, param);
323             }
324         }
325         for (XWPFParagraph paragraph : targetParagraphs) {
326             document.removeBodyElement(document.getPosOfParagraph(paragraph));
327         }
328     }
329 
330     /**
331      * 处理循环的表格行
332      *
333      * @param table              table
334      * @param targetTableRows    targetTableRows
335      * @param targetTableRowsPos targetTableRowsPos
336      * @param params             params
337      * @return void
338      * @Author LIZHIQIANG
339      * @Date Create in 2020/3/5 20:56
340      */
341     private static void processTableRows(XWPFTable table, List<XWPFTableRow> targetTableRows, List<Integer> targetTableRowsPos, JSONObject params) {
342         if (targetTableRows.isEmpty() || params.isEmpty()) {
343             return;
344         }
345         //默认key
346         String defaultKey = "listTables1";
347         JSONArray jsonArray = params.getJSONArray(defaultKey);
348         if (jsonArray == null) {
349             return;
350         }
351 
352         for (int i = 0; i < targetTableRows.size(); i++) {
353             XWPFTableRow row = targetTableRows.get(i);
354             //循环需要替换的数据
355             for (Object data : jsonArray) {
356                 //参数 一次循环的参数
357                 JSONObject param = JSON.parseObject(data.toString());
358                 XWPFTableRow newRow = table.createRow();
359                 copyTableRow(row, newRow);
360                 List<XWPFTableCell> newRowCells = newRow.getTableCells();
361                 for (XWPFTableCell newRowCell : newRowCells) {
362                     List<XWPFParagraph> paragraphs = newRowCell.getParagraphs();
363                     for (XWPFParagraph paragraph : paragraphs) {
364                         processParagraph(paragraph, param);
365                     }
366                 }
367             }
368             table.removeRow(targetTableRowsPos.get(i));
369         }
370     }
371 
372 
373     /**
374      * 复制单元
375      *
376      * @param target target
377      * @param source source
378      */
379     private static void copyRun(XWPFRun source, XWPFRun target) {
380         // 设置run属性
381         target.getCTR().setRPr(source.getCTR().getRPr());
382         // 设置文本
383         target.setText(source.text());
384     }
385 
386     /**
387      * 复制段落
388      *
389      * @param source 源段落
390      * @param target 目标段落
391      */
392     private static void copyParagraph(XWPFParagraph source, XWPFParagraph target) {
393         // 设置run属性
394         target.getCTP().setPPr(source.getCTP().getPPr());
395         //清除新段落的单元
396         List<XWPFRun> targetRuns = target.getRuns();
397         if (targetRuns != null && targetRuns.size() > 0) {
398             for (int pos = 0; pos < targetRuns.size(); pos++) {
399                 target.removeRun(pos);
400             }
401         }
402         //复制源段落的单元到目标段落
403         for (XWPFRun sourceRun : source.getRuns()) {
404             XWPFRun targetRun = target.createRun();
405             copyRun(sourceRun, targetRun);
406         }
407     }
408 
409     /**
410      * 复制表格列
411      *
412      * @param source 源
413      * @param target 目标
414      */
415     private static void copyTableCell(XWPFTableCell source, XWPFTableCell target) {
416         // 设置TableCell属性
417         target.getCTTc().setTcPr(source.getCTTc().getTcPr());
418 
419         List<XWPFParagraph> targetParagraphs = target.getParagraphs();
420         if (targetParagraphs != null && targetParagraphs.size() > 0) {
421             for (int pos = 0; pos < targetParagraphs.size(); pos++) {
422                 target.removeParagraph(pos);
423             }
424         }
425         List<XWPFParagraph> sourceParagraphs = source.getParagraphs();
426         for (XWPFParagraph sourceParagraph : sourceParagraphs) {
427             XWPFParagraph targetParagraph = target.addParagraph();
428             copyParagraph(sourceParagraph, targetParagraph);
429         }
430     }
431 
432     /**
433      * 复制表格行
434      *
435      * @param source 源
436      * @param target 目标
437      */
438     private static void copyTableRow(XWPFTableRow source, XWPFTableRow target) {
439         // 设置TableRow属性
440         target.getCtRow().setTrPr(source.getCtRow().getTrPr());
441 
442         List<XWPFTableCell> sourceCells = source.getTableCells();
443         List<XWPFTableCell> targetCells = target.getTableCells();
444         //复制列及其属性和内容
445         for (int pos = 0; pos < sourceCells.size(); pos++) {
446             XWPFTableCell sourceCell = sourceCells.get(pos);
447             XWPFTableCell targetCell = targetCells.get(pos);
448             copyTableCell(sourceCell, targetCell);
449         }
450     }
451 
452 }
View Code

 

posted @ 2020-09-07 10:20  lu亮宇  阅读(184)  评论(0编辑  收藏  举报