package com.farriver.bwf.common.utilities; import com.alibaba.fastjson2.JSON; import org.apache.poi.xwpf.usermodel.*; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import java.io.*; import java.lang.reflect.Field; import java.util.*; public class DocxExportUtil { private static final Logger logger = LoggerFactory.getLogger(DateTimeUtils.class); @NotNull public static HashMap getHashMap(T model) { HashMap map = new HashMap(); Class clazz1 = model.getClass(); Field[] declaredFields = clazz1.getDeclaredFields(); for (Field field : declaredFields) { field.setAccessible(true); Object value = null; try { String key = String.format("${%s}", field.getName()); value = field.get(model); if (value instanceof String[]) { value = JSON.toJSONString(value); } else if (value instanceof Date) { value = DateTimeUtils.dateToString((Date) value, "yyyy/MM/dd hh:mm"); } map.put(key, value); } catch (IllegalAccessException e) { logger.error(e.getMessage(), e); } } return map; } /** * 替换段落里面的变量 * * @param paragraph * @param map */ public static void replaceParagraph(XWPFParagraph paragraph, Map map) { List runs = paragraph.getRuns(); for (int i = 0; i < runs.size(); i++) { XWPFRun run = runs.get(i); String tkey = run.toString(); if (tkey == null) { return; } for (String key : map.keySet()) { if (tkey.equals(key)) { int size = run.getFontSize(); if (size == -1) { size = 14; } String fontFamily = run.getFontFamily(); //因为直接调用setText()方法替换文本时,会在底层重新创建一个run,所以在设置文本之前要先删除当前run paragraph.removeRun(i); if (map != null && map.get(key) != null) { String runText = map.get(key).toString(); if (runText != null) { if (runText.indexOf("\r\n") != -1) { String[] texts = runText.split("\r\n"); List tmp = new ArrayList<>(); for (String text : texts) { if (text != null && text.length() != 0) { tmp.add(text); } } texts = tmp.toArray(new String[0]); for (int n = 0; n < texts.length; n++) { XWPFRun newRun = paragraph.createRun(); newRun.setText(" " + texts[n].trim()); if (texts.length > 1 && n != texts.length - 1) { newRun.addBreak(); } newRun.setText(runText); newRun.setFontSize(size); newRun.setFontFamily(fontFamily); } } else if (runText.indexOf("\n") != -1) { String[] texts = runText.split("\n"); List tmp = new ArrayList<>(); for (String text : texts) { if (text != null && text.length() != 0) { tmp.add(text.trim()); } } texts = tmp.toArray(new String[0]); for (int n = 0; n < texts.length; n++) { XWPFRun newRun = paragraph.createRun(); newRun.setText(" " + texts[n].trim()); if (texts.length > 1 && n != texts.length - 1) { newRun.addBreak(); } newRun.setFontSize(size); newRun.setFontFamily(fontFamily); } } else { //重新创建一个run用于设置文本 XWPFRun newrun = paragraph.insertNewRun(i); newrun.setText(runText); newrun.setFontSize(size); newrun.setFontFamily(fontFamily); } } } } } } } /** * 替换页眉里面的变量 * * @param Header * @param map */ public static void replaceHeader(XWPFHeader Header, Map map) { //获取表 List tableList = Header.getTables(); if (tableList != null && tableList.size() > 0) { for (int i = 0; i < tableList.size(); i++) { XWPFTable table = tableList.get(i); //获取行 List rows = table.getRows(); for (XWPFTableRow row : rows) { //获取单元格 List cells = row.getTableCells(); for (XWPFTableCell cell : cells) { //获取单元格内容 List paragraphs = cell.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { // paragraph.setAlignment(ParagraphAlignment.LEFT); replaceParagraph(paragraph, map); } } } } } else { List paragraphs = Header.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { // paragraph.setAlignment(ParagraphAlignment.LEFT); replaceParagraph(paragraph, map); } } } /** * 替换页脚里面表格的变量 * * @param Footer * @param map */ public static void replaceFooter(XWPFFooter Footer, Map map) { //获取表 List tableList = Footer.getTables(); if (tableList != null && tableList.size() > 0) { for (int i = 0; i < tableList.size(); i++) { XWPFTable table = tableList.get(i); //获取行 List rows = table.getRows(); //获取单元格 for (XWPFTableRow row : rows) { List cells = row.getTableCells(); for (XWPFTableCell cell : cells) { //获取段落 List paragraphs = cell.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { // paragraph.setAlignment(ParagraphAlignment.LEFT); replaceParagraph(paragraph, map); } } } } } else { List paragraphs = Footer.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { // paragraph.setAlignment(ParagraphAlignment.LEFT); replaceParagraph(paragraph, map); } } } /** * 替换表格里面的变量 * * @param document * @param map */ public static void replaceInTable(XWPFDocument document, Map map) throws Exception { Iterator iterator = document.getTablesIterator(); while (iterator.hasNext()) { //获取表 XWPFTable table = iterator.next(); //获取行 List rows = table.getRows(); for (XWPFTableRow row : rows) { //获取单元格 List cells = row.getTableCells(); for (XWPFTableCell cell : cells) { List paragraphs = cell.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { //paragraph.setAlignment(ParagraphAlignment.LEFT); replaceParagraph(paragraph, map); } } } } } /** * 导出docx * * @param templatePath * @param outPath * @param map */ public static boolean getDocx(String templatePath, String outPath, Map map) { XWPFDocument document = null; try { File file = new File(templatePath); InputStream in = new FileInputStream(file); document = new XWPFDocument(in); //替换页眉变量 Iterator headerIterator = document.getHeaderList().iterator(); while (headerIterator.hasNext()) { XWPFHeader header = headerIterator.next(); replaceHeader(header, map); } //替换页脚变量 Iterator footerIterator = document.getFooterList().iterator(); while (footerIterator.hasNext()) { XWPFFooter footer = footerIterator.next(); replaceFooter(footer, map); } //替换表格里面的变量 replaceInTable(document, map); // 如果文件夹不存在 则建立新文件夹 File dir = new File(outPath); if (!dir.exists() == false) { dir.mkdirs(); } ByteArrayOutputStream bos = new ByteArrayOutputStream(); OutputStream out = new FileOutputStream(outPath); document.write(bos); out.write(bos.toByteArray()); bos.close(); out.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } finally { try { if (document != null) { document.close(); } } catch (IOException e) { e.printStackTrace(); } } } public static ResponseEntity ExportBOL(HashMap map, String templatePath) { var baos = new ByteArrayOutputStream(); var headers = new HttpHeaders(); XWPFDocument document = null; try { File file = new File(templatePath); InputStream in = new FileInputStream(file); document = new XWPFDocument(in); //替换页眉变量 Iterator headerIterator = document.getHeaderList().iterator(); while (headerIterator.hasNext()) { XWPFHeader header = headerIterator.next(); DocxExportUtil.replaceHeader(header, map); } //替换页脚变量 Iterator footerIterator = document.getFooterList().iterator(); while (footerIterator.hasNext()) { XWPFFooter footer = footerIterator.next(); DocxExportUtil.replaceFooter(footer, map); } //替换表格里面的变量 DocxExportUtil.replaceInTable(document, map); headers.setContentDispositionFormData("attachment", new String((UUID.randomUUID() + ".docx").getBytes("UTF-8"), "ISO-8859-1")); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); document.write(baos); return new ResponseEntity(baos.toByteArray(), headers, HttpStatus.CREATED); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { try { if (document != null) { document.close(); } } catch (IOException e) { logger.error(e.getMessage(), e); } } return new ResponseEntity(baos.toByteArray(), headers, HttpStatus.CREATED); } public static ResponseEntity ExportBOL(HashMap map, InputStream inputStream) { var baos = new ByteArrayOutputStream(); var headers = new HttpHeaders(); XWPFDocument document = null; try { document = new XWPFDocument(inputStream); //替换页眉变量 Iterator headerIterator = document.getHeaderList().iterator(); while (headerIterator.hasNext()) { XWPFHeader header = headerIterator.next(); DocxExportUtil.replaceHeader(header, map); } //替换页脚变量 Iterator footerIterator = document.getFooterList().iterator(); while (footerIterator.hasNext()) { XWPFFooter footer = footerIterator.next(); DocxExportUtil.replaceFooter(footer, map); } //替换表格里面的变量 DocxExportUtil.replaceInTable(document, map); headers.setContentDispositionFormData("attachment", new String((UUID.randomUUID() + ".docx").getBytes("UTF-8"), "ISO-8859-1")); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); document.write(baos); return new ResponseEntity(baos.toByteArray(), headers, HttpStatus.CREATED); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { try { if (document != null) { document.close(); } } catch (IOException e) { logger.error(e.getMessage(), e); } } return new ResponseEntity(baos.toByteArray(), headers, HttpStatus.CREATED); } }