poi导出word文件(带表格)
一.背景介绍
现有业务需求根据前端页面上所选的时间和列,来生成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);
}
}