POI生成word
项目中,经常需要导出word文件,而有些项目导出时没有模板,需要自动生成文件并导出。
在此背景下,本人调研了两个技术来自动生成:spiredoc和poi
spiredoc的具体使用在我之前的一篇博客里具体讲到了,今天主要分享下poi的使用方法,主要有:文档的生成,主要样式的设置,表格的生成(包括单元格的合并等),页眉和页脚的设置等等
话不多说,直接上代码:
pom引入依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.15</version>
</dependency>
java代码如下:
package com.glodon.doc;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigInteger;
/**
* @Author: yinjw-b
* @Date: 2020/11/25 16:23
* @Description:
*/
public class ExportWordTest {
public static void main(String[] args) throws Exception {
//生成文档
XWPFDocument document = new XWPFDocument();
//文件输出流
FileOutputStream out = new FileOutputStream(new File("D:\\信用文档.docx"));
//添加标题
createDocumentTitle(document);
// 信息汇总
createSecondTitle(document, "信息汇总");
createSummaryCredit(document);
// 基本信息
createSecondTitle(document, "基本信息");
createBaseInfo(document);
CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(document, sectPr);
//添加页眉
CTP ctpHeader = CTP.Factory.newInstance();
CTR ctrHeader = ctpHeader.addNewR();
CTText ctHeader = ctrHeader.addNewT();
String headerText = "广联达西安科技有限公司";
ctHeader.setStringValue(headerText);
XWPFParagraph headerParagraph = new XWPFParagraph(ctpHeader, document);
//设置为右对齐
headerParagraph.setAlignment(ParagraphAlignment.RIGHT);
XWPFParagraph[] parsHeader = new XWPFParagraph[1];
parsHeader[0] = headerParagraph;
policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT, parsHeader);
//添加页脚
CTP ctpFooter = CTP.Factory.newInstance();
CTR ctrFooter = ctpFooter.addNewR();
CTText ctFooter = ctrFooter.addNewT();
String footerText = "GLODON";
ctFooter.setStringValue(footerText);
XWPFParagraph footerParagraph = new XWPFParagraph(ctpFooter, document);
headerParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFParagraph[] parsFooter = new XWPFParagraph[1];
parsFooter[0] = footerParagraph;
policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, parsFooter);
document.write(out);
out.close();
System.out.println("create_table document written success.");
}
// word跨列合并单元格
public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
if (cellIndex == fromCell) {
// The first merged cell is set with RESTART merge value
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
} else {
// Cells which join (merge) the first one, are set with CONTINUE
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
// word跨行并单元格
public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
if (rowIndex == fromRow) {
// The first merged cell is set with RESTART merge value
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
} else {
// Cells which join (merge) the first one, are set with CONTINUE
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
}
}
}
// 单元格字体设置
private static void setParagraph(XWPFTableCell cell, String cellText) {
CTP ctp = CTP.Factory.newInstance();
XWPFParagraph p = new XWPFParagraph(ctp, cell);
p.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = p.createRun();
run.setText(cellText);
run.setFontFamily("宋体");
run.setFontSize(11);
cell.setParagraph(p);
}
// 表格标题单元格设置
private static void setTableTitle(XWPFTableCell cell, String cellText) {
CTP ctp = CTP.Factory.newInstance();
XWPFParagraph p = new XWPFParagraph(ctp, cell);
p.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = p.createRun();
run.setText(cellText);
run.setFontFamily("宋体");
run.setFontSize(11);
cell.setParagraph(p);
cell.setColor("BFBFBF");
}
/**
* 添加标题
* @param document
*/
private static void createDocumentTitle(XWPFDocument document) {
//添加标题
XWPFParagraph titleParagraph = document.createParagraph();
//设置段落居中
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleParagraphRun = titleParagraph.createRun();
titleParagraphRun.setText("个人信用评价记录");
titleParagraphRun.setFontFamily("宋体");
titleParagraphRun.setFontSize(22);
titleParagraphRun.setBold(true);
}
/**
* 创建二级标题
* @param document
*/
private static void createSecondTitle(XWPFDocument document, String text){
XWPFParagraph paragraph1 = document.createParagraph();
paragraph1.setAlignment(ParagraphAlignment.LEFT);
XWPFRun run1 = paragraph1.createRun();
run1.addBreak();
run1.setText(text);
run1.addBreak();
run1.setFontFamily("黑体");
run1.setFontSize(16);
run1.setBold(true);
}
/**
* 信息汇总
* @param document
*/
private static void createSummaryCredit(XWPFDocument document){
XWPFParagraph paragraph2 = document.createParagraph();
paragraph2.setAlignment(ParagraphAlignment.LEFT);
XWPFRun run2 = paragraph2.createRun();
run2.setText("个人姓名:" + "广联达");
run2.addBreak();
run2.addBreak();
run2.setText("申请时间:" + "2020-11-10 10:12:27");
run2.addBreak();
run2.addBreak();
run2.setText("生效时间:" + "2020-11-10 13:49:25");
run2.addBreak();
run2.addBreak();
run2.setText("失效时间:" + "2021-11-09 13:49:25");
run2.addBreak();
run2.addBreak();
run2.setText("总分:" + "86");
run2.addBreak();
run2.addBreak();
run2.setText("等级:" + "AAAA");
run2.addBreak();
run2.addBreak();
run2.setText("基本信息得分:" + "70");
run2.addBreak();
run2.addBreak();
run2.setText("良好行为得分:" + "18");
run2.addBreak();
run2.addBreak();
run2.setText("不良行为减分:" + "-2");
run2.addBreak();
run2.addBreak();
run2.setFontFamily("宋体");
run2.setFontSize(11);
}
/**
* 基本信息
* @param document
*/
private static void createBaseInfo(XWPFDocument document) {
// 画表格
for (int i = 0; i < 3; i++) {
XWPFParagraph paragraph4 = document.createParagraph();
paragraph4.setAlignment(ParagraphAlignment.LEFT);
XWPFRun run4 = paragraph4.createRun();
run4.addBreak();
run4.setText("测试");
run4.addBreak();
run4.setText("-------------------------------------------------");
run4.addBreak();
run4.setFontFamily("宋体");
run4.setFontSize(11);
//工作经历表格
XWPFTable ComTable = document.createTable();
//列宽自动分割
CTTblWidth comTableWidth = ComTable.getCTTbl().addNewTblPr().addNewTblW();
comTableWidth.setType(STTblWidth.DXA);
comTableWidth.setW(BigInteger.valueOf(9072));
//表格第一个标题
XWPFTableRow comTableRowOne = ComTable.getRow(0);
setTableTitle(comTableRowOne.getCell(0), "评分");
comTableRowOne.addNewTableCell().setText("");
for (int i1 = 0; i1 < 3; i1++) {
XWPFTableRow comTableRowTwo = ComTable.createRow();
setParagraph(comTableRowTwo.getCell(0), "评分内容" + i1);
setParagraph(comTableRowTwo.getCell(1), "这是评分内容,评分内容" + i1);
}
//表格第二个标题
XWPFTableRow comTableRowThree = ComTable.createRow();
setTableTitle(comTableRowThree.getCell(0), "评分信息");
for (int i1 = 0; i1 < 2; i1++) {
XWPFTableRow comTableRowTwo = ComTable.createRow();
setParagraph(comTableRowTwo.getCell(0), "评分信息" + i1);
setParagraph(comTableRowTwo.getCell(1), "这是提交的信息" + i1);
}
mergeCellsHorizontal(ComTable, 0, 0, 1);
mergeCellsHorizontal(ComTable, 4, 0, 1);
}
}
}
生成文档效果如下:
效果好像还不错,这些都是poi的常用操作,适用于大部分使用场景,当然其他操作可以参考poi官方文档