一.背景介绍
现有业务需求根据前端页面上所选的时间和列,来生成word表格,方便打印。
一.POM
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.14</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.14</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>ooxml-schemas</artifactId> <version>1.4</version> </dependency>
二.Controller
@PostMapping("/export") public void export(HttpServletRequest request, HttpServletResponse response, @RequestParam String startTime, @RequestParam String endTime, @RequestParam String[] keys, @RequestParam String[] names) throws Exception { XWPFDocument doc = this.exportService.exportFlight(request, response, startTime, endTime, keys, names); String fileName = "Word-" + startTime + "-" + endTime + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".docx"; String headStr = "attachment; filename=\"" + fileName + "\""; response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", headStr); response.setCharacterEncoding("UTF-8"); OutputStream out = response.getOutputStream(); doc.write(out); }
三.API介绍
XWPFDocument word文档
XWPFParagraph 段落
XWPFHeader 页眉
XWPFFooter 页脚
XWPFTable 表格
XWPFRun 段落中的文字
四.Service
@Override public XWPFDocument exportFlight(HttpServletRequest request, HttpServletResponse response, String startTime, String endTime, String[] keys, String[] names) throws IOException { List<Object> list = new ArrayList<>();//此处获取指定时间范围内的数据 XWPFDocument doc = new XWPFDocument(); //设置页脚 WordUtil.createDefaultFooter(doc); //设置页边距 WordUtil.setMargin(doc, 1000, 1000, 500, 100); //设置标题 WordUtil.setParagraph(doc, "标题", "宋体", 16, 10, true, ParagraphAlignment.CENTER); //设置副标题 WordUtil.setParagraph(doc, startTime + "到" + endTime, "宋体", 10, 10, true, ParagraphAlignment.RIGHT); //获取列,第一列默认为序号 List<String> nameList = new ArrayList<>(Arrays.asList(names));
nameList.add(0,"序号"); List<String> keyList = new ArrayList<>(Arrays.asList(keys));
keyList.add(0,"NO");
//总列数 int colTotalCount = nameList.size(); //总条数 int dataCount = flightList.size(); //创建表格 XWPFTable xTable = doc.createTable(1, colTotalCount); //设置边框 WordUtil.setTableBolder(xTable, 10, "000000"); // 创建表头数据 int i = 0; for (int j = 0; j < colTotalCount; j++) { WordUtil.setCellText(xTable.getRow(i).getCell(j), nameList.get(j), getCellWidth(keyList.get(j)), "宋体", 10, true); } // 创建表格内容 i++; for (int i2 = i; i2 < dataCount; i2++) { XWPFTableRow row = xTable.insertNewTableRow(i2); row.setHeight(300); for (int j = 0; j < colTotalCount; j++) { XWPFTableCell cell = row.createCell(); XWPFRun run; run = WordUtil.setTableCellStyle(cell, ParagraphAlignment.CENTER, "微软雅黑", 9, false); if (j == 0) { //序号 run.setText(String.valueOf(i2)); }else { //获取内容 Object object = list.get(i2);
run.setText(object.toString()); } } } return doc; }
设置列宽方法
/** * 设置列宽 * * @param key * @return */ private static int getCellWidth(String key) {
//根据不同的列设置列宽 int cwidth = 2000; if ("NO".equals(key)) { cwidth = 800; }return cwidth; }
Word工具类方法

package com.xxx.xxx.utils; import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; import org.apache.poi.xwpf.usermodel.*; import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute; import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; import java.io.IOException; import java.math.BigInteger; import java.util.List; /** * @Classname WordUtil * @Description 导出WORD工具类 * @Date 2020/11/24 10:40 * @Author author */ public class WordUtil { /** * 创建默认的页脚(该页脚主要只居中显示页码) * * @param docx XWPFDocument文档对象 * @return * @throws IOException IO异常 */ public static void createDefaultFooter(XWPFDocument docx) throws IOException { CTSectPr sectPr = docx.getDocument().getBody().addNewSectPr(); XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(docx, sectPr); XWPFFooter footer = headerFooterPolicy.createFooter(STHdrFtr.DEFAULT); XWPFParagraph paragraph = footer.getParagraphArray(0); paragraph.setAlignment(ParagraphAlignment.CENTER); paragraph.setVerticalAlignment(TextAlignment.CENTER); CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab(); tabStop.setVal(STTabJc.CENTER); XWPFRun run = paragraph.createRun(); run.addTab(); run = paragraph.createRun(); run.setText("第"); run = paragraph.createRun(); CTFldChar fldChar = run.getCTR().addNewFldChar(); fldChar.setFldCharType(STFldCharType.Enum.forString("begin")); run = paragraph.createRun(); CTText ctText = run.getCTR().addNewInstrText(); ctText.setStringValue("PAGE \\* MERGEFORMAT"); ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve")); fldChar = run.getCTR().addNewFldChar(); fldChar.setFldCharType(STFldCharType.Enum.forString("end")); run = paragraph.createRun(); run.setText("页/共"); run = paragraph.createRun(); fldChar = run.getCTR().addNewFldChar(); fldChar.setFldCharType(STFldCharType.Enum.forString("begin")); run = paragraph.createRun(); ctText = run.getCTR().addNewInstrText(); ctText.setStringValue("NUMPAGES \\* MERGEFORMAT "); ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve")); fldChar = run.getCTR().addNewFldChar(); fldChar.setFldCharType(STFldCharType.Enum.forString("end")); run = paragraph.createRun(); run.setText("页"); } /** * 设置表头内容 * * @param cell * @param text * @param width * @param fontFamily * @param fontSize * @param bold */ public static void setCellText(XWPFTableCell cell, String text, int width, String fontFamily, int fontSize, boolean bold) { XWPFParagraph paragraph = cell.getParagraphs().get(0); XWPFRun run = paragraph.createRun(); run.setFontFamily(fontFamily); run.setFontSize(fontSize); run.setBold(bold); run.setText(text); CTTc cttc = cell.getCTTc(); CTTcPr cellPr = cttc.addNewTcPr(); cellPr.addNewTcW().setW(BigInteger.valueOf(width)); cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); CTTcPr ctPr = cttc.addNewTcPr(); ctPr.addNewVAlign().setVal(STVerticalJc.CENTER); cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER); } /** * 设置页边距 * * @param doc * @param left * @param right * @param top * @param bottom */ public static void setMargin(XWPFDocument doc, int left, int right, int top, int bottom) { CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr(); CTPageMar pageMar = sectPr.addNewPgMar(); pageMar.setLeft(BigInteger.valueOf(left)); pageMar.setRight(BigInteger.valueOf(right)); pageMar.setTop(BigInteger.valueOf(top)); pageMar.setBottom(BigInteger.valueOf(bottom)); } /** * 设置段落文本 * * @param doc * @param text * @param fontFamily * @param fontSize * @param textPosition * @param bold * @param paragraphAlignment */ public static void setParagraph(XWPFDocument doc, String text, String fontFamily, int fontSize, int textPosition, boolean bold, ParagraphAlignment paragraphAlignment) { XWPFParagraph xp = doc.createParagraph(); xp.setSpacingBefore(0); XWPFRun r1 = xp.createRun(); r1.setText(text); r1.setFontFamily(fontFamily); r1.setFontSize(fontSize); r1.setTextPosition(textPosition); r1.setBold(bold); xp.setAlignment(paragraphAlignment); } /** * 设置表格样式 * * @param cell * @param paragraphAlignment * @param fontFamily * @param fontSize * @param bold * @return */ public static XWPFRun setTableCellStyle(XWPFTableCell cell, ParagraphAlignment paragraphAlignment, String fontFamily, int fontSize, boolean bold) { XWPFParagraph paragraph = cell.getParagraphs().get(0); paragraph.setAlignment(paragraphAlignment); XWPFRun run = paragraph.createRun(); run.setFontFamily(fontFamily); run.setFontSize(fontSize); run.setBold(bold); return run; } /** * 设置边框 * * @param xTable * @param bolderSize */ public static void setTableBolder(XWPFTable xTable, int bolderSize, String color) { CTTblBorders borders = xTable.getCTTbl().getTblPr().addNewTblBorders(); CTBorder hBorder = borders.addNewInsideH(); hBorder.setVal(STBorder.Enum.forString("single")); hBorder.setSz(new BigInteger(String.valueOf(bolderSize))); hBorder.setColor(color); CTBorder vBorder = borders.addNewInsideV(); vBorder.setVal(STBorder.Enum.forString("single")); vBorder.setSz(new BigInteger(String.valueOf(bolderSize))); vBorder.setColor(color); CTBorder lBorder = borders.addNewLeft(); lBorder.setVal(STBorder.Enum.forString("single")); lBorder.setSz(new BigInteger(String.valueOf(bolderSize))); lBorder.setColor(color); CTBorder rBorder = borders.addNewRight(); rBorder.setVal(STBorder.Enum.forString("single")); rBorder.setSz(new BigInteger(String.valueOf(bolderSize))); rBorder.setColor(color); CTBorder tBorder = borders.addNewTop(); tBorder.setVal(STBorder.Enum.forString("single")); tBorder.setSz(new BigInteger(String.valueOf(bolderSize))); tBorder.setColor(color); CTBorder bBorder = borders.addNewBottom(); bBorder.setVal(STBorder.Enum.forString("single")); bBorder.setSz(new BigInteger(String.valueOf(bolderSize))); bBorder.setColor(color); } }
五.效果