在网上看了好多其他人的案例,做了一些处理和简单的封装,大家可以参考学习使用。
看了很多案例,感觉还是要封装一个标准的Word Java生成Util工具包,方便大家使用。
里面有很多地方需要自己去做处理,包括:字体大小,颜色,间距等等 。所以如果只是简单想生成一个word 可以使用这个Util,但是如果需要一些特殊处理,就需要 自己基于这个Util做一些扩展了。其中 STD 是标准的意思,创建一个标准的 行 或 表格 。默认了样式。
maven poi-ooxml 基于4.0.1
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
POIWordUtil.java封装。
package com.hd.common.util.excel;
import com.hd.common.util.logger.LoggerUtil;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* apache poi word操作封装 .
*/
public class POIWordUtil {
public static final String PLACEHOLDER_TOC = "toc";
public static final String HEADING_1 = "Heading1";
public static final String HEADING_2 = "Heading2";
public static final String HEADING_3 = "Heading3";
public static final String HEADING_4 = "Heading4";
public static final String COLOR_BLACK = "000000";
public static final String COLOR_WHITE = "ffffff";
public static final int FONT_SIZE_22 = 22;
public static final int FONT_SIZE_21 = 21;
public static final int FONT_SIZE_20 = 20;
public static final int FONT_SIZE_19 = 19;
public static final int FONT_SIZE_18 = 18;
public static final int FONT_SIZE_17 = 17;
public static final int FONT_SIZE_16 = 16;
public static final int FONT_SIZE_15 = 15;
public static final int FONT_SIZE_14 = 14;
public static final int FONT_SIZE_13 = 13;
public static final int FONT_SIZE_12 = 12;
public static final int POSITION_LEFT = 1;
public static final int POSITION_CENTER = 2;
public static final int POSITION_RIGHT = 3;
/**
* 创建一个Word文档
* @return
*/
public static final XWPFDocument createSTDDocument(){
XWPFDocument document = new XWPFDocument();
//自定义标题样式
addCustomHeadingStyle(document,HEADING_1,1);
addCustomHeadingStyle(document,HEADING_2,2);
addCustomHeadingStyle(document,HEADING_3,3);
addCustomHeadingStyle(document,HEADING_4,4);
return document;
}
/**
* 插入一个目录
* @param document
* @param tocCatalogueName
*/
public static final XWPFDocument insertSTDCatalogue(XWPFDocument document, String tocCatalogueName){
XWPFParagraph paragTOCName = document.createParagraph();
paragTOCName.setAlignment(ParagraphAlignment.CENTER);//位置居中
XWPFRun tocRunName = paragTOCName.createRun();
tocRunName.setText(tocCatalogueName);//"目录"
tocRunName.setColor(COLOR_BLACK);
tocRunName.setFontSize(FONT_SIZE_16);
//目录占位
XWPFParagraph paragTOC = document.createParagraph();
XWPFRun tocRun = paragTOC.createRun();
tocRun.setText(PLACEHOLDER_TOC);
return document;
}
/**
* 插入一个标准的图片
* @param document
* @param name
* @param in
* @throws IOException
* @throws InvalidFormatException
*/
public static final XWPFDocument insertSTDImgPNG(XWPFDocument document, String name, InputStream in) throws IOException, InvalidFormatException {
//加入图片
XWPFParagraph firstParagrap = document.createParagraph();
//设置居中
firstParagrap.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = firstParagrap.createRun();
// run.addBreak();
run.addPicture(in, XWPFDocument.PICTURE_TYPE_PNG, name, Units.toEMU(410), Units.toEMU(200));
return document;
}
/**
* 插入一个标准的文本
* @param document
* @param text 文本
* @param color 颜色
* @param fontSize 字体大小
* @param position 位置 左对齐 居中 右对齐
* @param isTab 是否在文本前加tab
* @param isBGPColor 是否设置当前段落背景颜色
*/
public static final XWPFDocument insertSTDString(XWPFDocument document, String text, String color
, int fontSize, int position, String BGPColor, boolean isTab, boolean isBGPColor){
XWPFParagraph paragrap = document.createParagraph();
XWPFRun run = paragrap.createRun();
if(isTab) run.addTab();//tab键
switch (position){//位置
case POSITION_LEFT:
paragrap.setAlignment(ParagraphAlignment.LEFT);
break;
case POSITION_CENTER:
paragrap.setAlignment(ParagraphAlignment.CENTER);
break;
case POSITION_RIGHT:
paragrap.setAlignment(ParagraphAlignment.RIGHT);
break;
}
if(isBGPColor){//设置段落背景颜色
CTShd cTShd = run.getCTR().addNewRPr().addNewShd();
cTShd.setVal(STShd.CLEAR);
cTShd.setFill(BGPColor);
}
run.setText(text);
run.setColor(color);
run.setFontSize(fontSize);
return document;
}
public static final XWPFDocument insertSTDString(XWPFDocument document, String text, String color, int fontSize, int position, boolean isTab){
return insertSTDString(document, text, color, fontSize, position, COLOR_WHITE, isTab, false);
}
public static final XWPFDocument insertSTDString(XWPFDocument document, String text, int position, boolean isTab){
return insertSTDString(document, text, COLOR_BLACK, position, isTab);
}
public static final XWPFDocument insertSTDString(XWPFDocument document, String text, String color, boolean isTab){
return insertSTDString(document, text, color, POSITION_LEFT, isTab);
}
public static final XWPFDocument insertSTDString(XWPFDocument document, String text, String color, int fontSize, boolean isTab){
return insertSTDString(document, text, color, fontSize, POSITION_LEFT, isTab);
}
public static final XWPFDocument insertSTDString(XWPFDocument document, String text, boolean isTab){
return insertSTDString(document, text, COLOR_BLACK, isTab);
}
/**
* 插入一个标准的表格
* @param document
* @param titles 标题数据
* @param tables 表格数据 其中 list.get(0)默认为 title信息
* @param isAutoDivision 是否自动列宽 true 自动 false 不自动
* @param isBorder 是否显示表格边框线 true 显示 false 不显示
* @return
*/
public static final XWPFDocument insertSTDTable(XWPFDocument document, List<String> titles, List<List<String>> tables, boolean isAutoDivision, boolean isBorder){
//工作经历表格
XWPFTable table = document.createTable();
if(isAutoDivision){
//列宽自动分割
CTTblWidth tableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
tableWidth.setType(STTblWidth.DXA);
tableWidth.setW(BigInteger.valueOf(9072));
}
if(!isBorder){
//isBorder = false 则去掉边框
table.getCTTbl().getTblPr().unsetTblBorders();
}
XWPFTableRow comTableRowOne = table.getRow(0);
if(titles != null){ //标题
for(int i = 0; i < titles.size(); i++){
String text = titles.get(i);
XWPFTableCell cell = null;
if(i == 0){
cell = comTableRowOne.getCell(0);
}else{
cell = comTableRowOne.addNewTableCell();
}
settingTableCellHorizontally(cell); //水平居中
settingTableCellVerticalCenter(cell);//垂直居中
//段落背景颜色
CTShd cTShd = cell.getCTTc().addNewTcPr().addNewShd();
cTShd.setVal(STShd.CLEAR);
cTShd.setFill("97FFFF");
cell.setText(text);//设置文本
}
}
//数据
tables.stream().forEach(beanList->{
XWPFTableRow tableRow = table.createRow();
for(int i = 0; i < beanList.size(); i++) {
String text = beanList.get(i);
XWPFTableCell cell = null;
if(tableRow.getCell(i) == null){
cell = tableRow.addNewTableCell();
}else{
cell = tableRow.getCell(i);
}
settingTableCellHorizontally(cell); //水平居中
settingTableCellVerticalCenter(cell);//垂直居中
cell.setText(text);
}
});
return document;
}
/**
* 设置表格中的数据 水平居中
* @param cell
*/
public static final void settingTableCellHorizontally(XWPFTableCell cell){
CTTc cttc = cell.getCTTc();
CTP ctp = cttc.getPList().get(0);
CTPPr ctppr = ctp.getPPr();
if (ctppr == null) {
ctppr = ctp.addNewPPr();
}
CTJc ctjc = ctppr.getJc();
if (ctjc == null) {
ctjc = ctppr.addNewJc();
}
ctjc.setVal(STJc.CENTER); //水平居中
}
/**
* 设置表格中的数据 垂直居中
* @param cell
*/
public static final void settingTableCellVerticalCenter(XWPFTableCell cell){
cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);//垂直居中
}
/**
* 插入一个标准标题
* @param document
* @param text
* @param styleHeading
* @param color
* @param fontSize
* @return
*/
public static final XWPFDocument insertSTDTitle(XWPFDocument document, String text, String styleHeading, String color, int fontSize){
XWPFParagraph paragraph = document.createParagraph();
paragraph.setStyle(styleHeading);
XWPFRun run = paragraph.createRun();
run.setText(text);
run.setColor(color);
run.setFontSize(fontSize);
return document;
}
public static final XWPFDocument insertSTDTitleHeading1(XWPFDocument document, String text){
return insertSTDTitle(document, text, HEADING_1, COLOR_BLACK, FONT_SIZE_18);
}
public static final XWPFDocument insertSTDTitleHeading2(XWPFDocument document, String text){
return insertSTDTitle(document, text, HEADING_2, COLOR_BLACK, FONT_SIZE_16);
}
public static final XWPFDocument insertSTDTitleHeading3(XWPFDocument document, String text){
return insertSTDTitle(document, text, HEADING_3, COLOR_BLACK, FONT_SIZE_14);
}
public static final XWPFDocument insertSTDTitleHeading4(XWPFDocument document, String text){
return insertSTDTitle(document, text, HEADING_4, COLOR_BLACK, FONT_SIZE_13);
}
/**
* 插入标准一个换行
* @param document
* @return
*/
public static final XWPFDocument insertSTDLineFeed(XWPFDocument document){
//两个表格之间加个换行
XWPFParagraph paragraph = document.createParagraph();
XWPFRun paragraphRun = paragraph.createRun();
paragraphRun.setText("\r");
return document;
}
/**
* 设置标准的页眉和页脚
* @param document
* @param headerText
* @param footerText
* @return
* @throws IOException
*/
public static final XWPFDocument settingSTDHeaderAndFooter(XWPFDocument document, String headerText, String footerText) {
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();
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();
ctFooter.setStringValue(footerText);
XWPFParagraph footerParagraph = new XWPFParagraph(ctpFooter, document);
footerParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFParagraph[] parsFooter = new XWPFParagraph[1];
parsFooter[0] = footerParagraph;
policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, parsFooter);
return document;
}
/**
* 写入指定的目录文件中
* @param document
* @param filePath D:\\upload\\test\\create_table.docx
* @throws IOException
*/
public static void toFileWord(XWPFDocument document, String filePath) throws IOException {
FileOutputStream out = new FileOutputStream(filePath);
document.write(out);
out.close();
}
/**
* 生成目录
* @param document
*/
public static void generateTOC(XWPFDocument document) {
String replaceText = "";
for (XWPFParagraph p : document.getParagraphs()) {
for (XWPFRun r : p.getRuns()) {
int pos = r.getTextPosition();
String text = r.getText(pos);
System.out.println(text);
if (text != null && text.contains(PLACEHOLDER_TOC)) {
text = text.replace(PLACEHOLDER_TOC, replaceText);
r.setText(text, 0);
addField(p, "TOC \\o \"1-3\" \\h \\z \\u");
// addField(p, "TOC \\h");
break;
}
}
}
}
private static void addField(XWPFParagraph paragraph, String fieldName) {
CTSimpleField ctSimpleField = paragraph.getCTP().addNewFldSimple();
ctSimpleField.setInstr(fieldName);
ctSimpleField.setDirty(STOnOff.TRUE);
ctSimpleField.addNewR().addNewT().setStringValue("<>");
}
/**
* 自定义标题
* @param docxDocument
* @param strStyleId
* @param headingLevel
*/
private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {
CTStyle ctStyle = CTStyle.Factory.newInstance();
ctStyle.setStyleId(strStyleId);
CTString styleName = CTString.Factory.newInstance();
styleName.setVal(strStyleId);
ctStyle.setName(styleName);
CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
indentNumber.setVal(BigInteger.valueOf(headingLevel));
// lower number > style is more prominent in the formats bar
ctStyle.setUiPriority(indentNumber);
CTOnOff onoffnull = CTOnOff.Factory.newInstance();
ctStyle.setUnhideWhenUsed(onoffnull);
// style shows up in the formats bar
ctStyle.setQFormat(onoffnull);
// style defines a heading of the given level
CTPPr ppr = CTPPr.Factory.newInstance();
ppr.setOutlineLvl(indentNumber);
ctStyle.setPPr(ppr);
XWPFStyle style = new XWPFStyle(ctStyle);
// is a null op if already defined
XWPFStyles styles = docxDocument.createStyles();
style.setType(STStyleType.PARAGRAPH);
styles.addStyle(style);
}
public static void main(String[] args) throws Exception {
//创建一个Word文档 实例
XWPFDocument document = POIWordUtil.createSTDDocument();
//设置目录
POIWordUtil.insertSTDCatalogue(document, "目录");
//插入一条 居中 字体20 黑色 的(标题 并不是word所识别的标题)
POIWordUtil.insertSTDString(document, "Java PoI", POIWordUtil.COLOR_BLACK, POIWordUtil.FONT_SIZE_20, POIWordUtil.POSITION_CENTER, false);
//插入一条 字体16 颜色696969 背景颜色97FFFF 的普通数据
POIWordUtil.insertSTDString(document, " Java POI 生成word文件。", "696969"
, POIWordUtil.FONT_SIZE_16, POIWordUtil.POSITION_LEFT, "97FFFF", false, true);
//插入一条 字体16 颜色696969 前面加入tab按键 的普通数据
POIWordUtil.insertSTDString(document, "Java POI 生成word文件。", "696969", POIWordUtil.FONT_SIZE_16, true);
//插入一条 图形报表 图片数据
String imgName = "图形报表.png";
FileInputStream imgOut = new FileInputStream(new File("D:\\upload\\test\\图形报表.png"));
POIWordUtil.insertSTDImgPNG(document, imgName, imgOut);
//插入一个 换行
POIWordUtil.insertSTDLineFeed(document);
//插入一个无线表格
List<List<String>> noBorderList = new ArrayList<>();
noBorderList.add(Arrays.asList("职位",": Java 开发工程师"));
noBorderList.add(Arrays.asList("姓名", ": miao"));
noBorderList.add(Arrays.asList("生日", ": xxxx-xx-xx"));
noBorderList.add(Arrays.asList("性别", ": 男"));
noBorderList.add(Arrays.asList("现居地", ": xx"));
POIWordUtil.insertSTDTable(document, null, noBorderList, true, false);
//插入一个 换行
POIWordUtil.insertSTDLineFeed(document);
//插入一个 有线表格
List<List<String>> borderList = new ArrayList<>();
borderList.add(Arrays.asList("2021-09-28", "至今", "seawater", "Java开发工程师"));
borderList.add(Arrays.asList("2021-09-28", "至今", "seawater", "Java开发工程师"));
POIWordUtil.insertSTDTable(document, Arrays.asList("开始时间", "结束时间", "公司名称", "title"), borderList, true, true);
//设置页眉页脚
POIWordUtil.settingSTDHeaderAndFooter(document, "Java POI create MS word file.", "http://blog.csdn.net/zhouseawater");
//插入标题
for (int i=0;i< 10;i++){
int num = i+1;
LoggerUtil.info("膜值:" + (i%4) + " 当前num:" + num);
if(i%4 == 0){
POIWordUtil.insertSTDTitleHeading1(document, "标题"+num);
}else if(i%4 == 1){
POIWordUtil.insertSTDTitleHeading2(document, "标题"+num);
}else if(i%4 == 2){
POIWordUtil.insertSTDTitleHeading3(document, "标题"+num);
}else{
POIWordUtil.insertSTDTitleHeading4(document, "标题"+num);
}
}
//生成 目录
POIWordUtil.generateTOC(document);
//存放到某一个文件里面
POIWordUtil.toFileWord(document, "D:\\upload\\test\\create_table.docx");
System.out.println("create_table document written success.");
}
}