我使用的poi版本是4.1.2。
下面开始使用之旅。
首先就是生成word的方法
/**
* 我们使用try with source方式即try(){}
* 可以将需要关闭的资源写在try后面的括号中,会自动关闭需要关闭的资源,避免资源得不到关闭
*
* 我们使用XWPFDocument可以用来生成docx后缀的word
* 使用输出流指定输出文件名称以及输出文件地址
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
try (XWPFDocument doc = new XWPFDocument(); OutputStream fos = new FileOutputStream("d:\\test\\wordTest.docx")) {
//将缓冲区的内容刷一下
fos.flush();
//将输出流中的内容写入word中
doc.write(fos);
} catch (Exception e) {
e.printStackTrace();
}
}
顺便提一下,如果想生成的word在网页上导出下载,需要配置一些东西并将使用该配置
具体如下:
public static OutputStream getWordOutputStream(HttpServletResponse response, String fileName) throws IOException {
response.setContentType("application/x-msdownload;");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 客户端不缓存
response.addHeader("Pragma", "no-cache");
response.addHeader("Cache-Control", "no-cache");
return response.getOutputStream();
}
下面运行一下main方法,看看效果如何。
执行main方法前,文件夹里面没有内容
执行main方法后,文件夹里面多出了文件
此时wordTest.docx里面还是没有内容的,我们现在开始对doc文件进行操作。
首先是对word内容进行操作,生成第一行标题内容
public static void main(String[] args) throws IOException {
try (XWPFDocument doc = new XWPFDocument(); OutputStream fos = new FileOutputStream("d:\\test\\wordTest.docx")) {
//创建段落
XWPFParagraph titleParagraph = doc.createParagraph();
//设置段落居中
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
//设置行距为传进来的size
setSingleLineSpacing(titleParagraph, 28);
//设置段落大纲等级
setOutLineLevel(titleParagraph, 0, "Heading0");
//获取段落文本对象
XWPFRun titleParagraphRun = titleParagraph.createRun();
//设置段落文本的文本内容
titleParagraphRun.setText("Hello Word!\tI`m coming!");
//设置段落文本的字体大小
titleParagraphRun.setFontSize(22);
//设置段落文本的字体
titleParagraphRun.setFontFamily("方正小标宋_GBK");
//将缓冲区的内容刷一下
fos.flush();
//将输出流中的内容写入word中
doc.write(fos);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void setOutLineLevel(XWPFParagraph paragraph, int level, String styleId) {
//获取设置样式对象
CTStyle ctStyle = CTStyle.Factory.newInstance();
//设置样式等级名称
ctStyle.setStyleId(styleId);
CTP ctp = paragraph.getCTP();
CTPPr ctpPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
CTDecimalNumber ctDecimalNumber = ctpPr.isSetOutlineLvl() ? ctpPr.getOutlineLvl() : ctpPr.addNewOutlineLvl();
//设置大纲等级,不设置默认为正文文本,设置的话0对应大纲等级一级
ctDecimalNumber.setVal(BigInteger.valueOf(level));
ctpPr.setOutlineLvl(ctDecimalNumber);
ctStyle.setPPr(ctpPr);
XWPFStyle style = new XWPFStyle(ctStyle);
//设置应用于段落
style.setType(STStyleType.PARAGRAPH);
}
private static CTSpacing setSingleLineSpacing(XWPFParagraph paragraph, int size) {
CTP ctp = paragraph.getCTP();
CTPPr ctpPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
CTSpacing ctSpacing = ctpPr.isSetSpacing() ? ctpPr.getSpacing() : ctpPr.addNewSpacing();
//设置文本缩进,文本之前缩进0
ctSpacing.setBefore(BigInteger.ZERO);
//设置文本缩进,文本之后缩进0
ctSpacing.setAfter(BigInteger.ZERO);
//设置行间距规则为精确值
ctSpacing.setLineRule(STLineSpacingRule.EXACT);
//设置行间距值,单位磅
ctSpacing.setLine(BigInteger.valueOf(size * 20));
return ctSpacing;
}
下面,我们来看效果如何。
我们可以看到文本确实居中了,字体大小22号就是对应二号字体,字体就是我们指定的字体。
我们可以看到大纲级别变成了1级,并且间距那一栏是我们想要的结果。
在添加一些内容
XWPFParagraph firstParagraph = doc.createParagraph();
//设置大纲等级为2级
setOutLineLevel(firstParagraph, 1,"Heading1");
XWPFRun firstParagraphRun = firstParagraph.createRun();
//设置首行缩进
firstParagraph.setIndentationFirstLine(420);
setSingleLineSpacing(firstParagraph, 29);
firstParagraphRun.setText("1.测试word操作1");
firstParagraphRun.setFontSize(16);
firstParagraphRun.setFontFamily("方正楷体_GBK");
//设置加粗
firstParagraphRun.setBold(true);
默认的对齐方式就是两端对齐,字体大小16号就是对应三号字体,字体就是我们指定的字体,并且wps自动识别到了我们的大纲级别。
我们可以看到大纲级别变成了2级,并且首行缩进确实设置成功了,但是首行缩进有一个计算的过程,首先是将我们输入的值除以20计算出一个值,然后转化为度量值。具体请看:Word字体大小对照换算表(字号、磅、英寸、像素)_word字体对照表_QAQ_King的博客-CSDN博客
继续进行操作
XWPFParagraph textParagraph = doc.createParagraph();
//设置对齐方式为两端对齐
textParagraph.setAlignment(ParagraphAlignment.BOTH);
textParagraph.setIndentationFirstLine(600);
CTSpacing textCTSpacing = setSingleLineSpacing(textParagraph, 28);
//设置段前间距
textCTSpacing.setBeforeLines(BigInteger.valueOf(19));
XWPFRun textParagraphRun = textParagraph.createRun();
textParagraphRun.setText("2.测试word操作2");
textParagraphRun.setFontFamily("方正仿宋_GBK");
textParagraphRun.setFontSize(16);
//设置斜体
textParagraphRun.setItalic(true);
我们可以看到没有设置大纲等级,wps是识别他为正文文本的。
大纲级别默认为正文文本,段前间距也是我们设置的值。
操作一下
XWPFParagraph allParagraph = doc.createParagraph();
allParagraph.setAlignment(ParagraphAlignment.LEFT);
allParagraph.setIndentationFirstLine(600);
setSingleLineSpacing(allParagraph, 28);
setOutLineLevel(allParagraph,2,"Heading2");
XWPFRun allParagraphRun = allParagraph.createRun();
allParagraphRun.setText("3.测试word操作3");
allParagraphRun.setFontSize(16);
allParagraphRun.setFontFamily("黑体");
下面我们对word里面的表格进行操作
//创建表
XWPFTable table = creatTable(doc);
//表格第一行
XWPFTableRow infoTableRowOne = table.getRow(0);
//设置表格高度
infoTableRowOne.setHeight(400);
//获取单元格
XWPFTableCell oneCell1 = infoTableRowOne.getCell(0);
//设置表格中数据居中
setTableCenter(oneCell1);
oneCell1.setText("test");
//获取到第一个单元格后使用此方法自动增加
XWPFTableCell oneCell2 = infoTableRowOne.addNewTableCell();
setTableCenter(oneCell2);
oneCell2.setText("word");
private static void setTableCenter(XWPFTableCell cell) {
CTTc ctTc = cell.getCTTc();
CTTcPr ctTcPr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();
CTVerticalJc ctVerticalJc = ctTcPr.isSetVAlign() ? ctTcPr.getVAlign() : ctTcPr.addNewVAlign();
//设置单元格垂直对齐方式为居中
ctVerticalJc.setVal(STVerticalJc.CENTER);
CTP ctp = ctTc.getPList().get(0);
CTPPr ctpPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
CTJc ctJc = ctpPr.isSetJc() ? ctpPr.getJc() : ctpPr.addNewJc();
//设置水平居中
ctJc.setVal(STJc.CENTER);
}
private static XWPFTable creatTable(XWPFDocument doc) {
//基本信息表格
XWPFTable table = doc.createTable();
//设置表格居中
table.setTableAlignment(TableRowAlign.CENTER);
//增加表格边框
CTTblBorders borders = table.getCTTbl().getTblPr().addNewTblBorders();
setBorder(borders);
//列宽自动分割
CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
infoTableWidth.setType(STTblWidth.DXA);
//设置表的列宽
infoTableWidth.setW(BigInteger.valueOf(9072));
return table;
}
private static void setBorder(CTTblBorders borders) {
CTBorder hBorder = borders.addNewInsideH();
hBorder.setVal(STBorder.SINGLE); // 线条类型
hBorder.setSz(BigInteger.ONE); // 线条大小
hBorder.setColor("000000"); // 设置颜色
CTBorder vBorder = borders.addNewInsideV();
vBorder.setVal(STBorder.SINGLE);
vBorder.setSz(BigInteger.ONE);
vBorder.setColor("000000");
CTBorder lBorder = borders.addNewLeft();
lBorder.setVal(STBorder.SINGLE);
lBorder.setSz(BigInteger.ONE);
lBorder.setColor("000000");
CTBorder rBorder = borders.addNewRight();
rBorder.setVal(STBorder.SINGLE);
rBorder.setSz(BigInteger.ONE);
rBorder.setColor("000000");
CTBorder tBorder = borders.addNewTop();
tBorder.setVal(STBorder.SINGLE);
tBorder.setSz(BigInteger.ONE);
tBorder.setColor("000000");
CTBorder bBorder = borders.addNewBottom();
bBorder.setVal(STBorder.SINGLE);
bBorder.setSz(BigInteger.ONE);
bBorder.setColor("000000");
}
看看效果如何:
循环添加数据试试
//循环添加数据
for (int i = 0; i < 5; i++) {
XWPFTableRow row = table.createRow();
row.setHeight(400);
XWPFTableCell cell1 = row.getCell(0);
cell1.setText("a" + i);
setTableCenter(cell1);
XWPFTableCell cell2 = row.getCell(1);
cell2.setText("b" + i);
setTableCenter(cell2);
}
看看效果
也是成功的出来了结果。
以上就是我对操作word的一个总结,如果大家还有什么其他的操作欢迎留言,我们一起探讨!