正文开始
网上很有多拿到word模板然后对其赋值的例子我就不多说了
我这边就只记录创建document table
public InputStream exportWordContainTable(){
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
XWPFDocument doc = createDocument();
doc.write(os);
return new ByteArrayInputStream(os.toByteArray());
} catch (Exception e) {
logger.error("setInputStream error", e);
}
return null;
}
public XWPFDocument createDocument(){
XWPFDocument doc = new XWPFDocument();
//添加标题
XWPFParagraph titleParagraph = doc.createParagraph();
//设置段落居中
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleParagraphRun = titleParagraph.createRun();
titleParagraphRun.setText("这是标题");
titleParagraphRun.setColor("000000");
titleParagraphRun.setFontSize(22);
titleParagraphRun.setFontFamily("宋体");
//创建表格
//这里的createTable括号里的值可以先不填,我这是直接创建了一个八行四列的表格
XWPFTable table = doc.createTable(8,4);
//去掉表格边框
table.getCTTbl().getTblPr().unsetTblBorders();
//设置表格宽度
setTableWidth(table, "9000");
//得到刚刚创建的第一行
XWPFTableRow row1 = table.getRow(0);
//下面这四句是给表格第一行的每一列设置宽度
//也不知道效果到底有没有 我加上去了 感觉是有的
//设置了一行之后 其他行的默认样式也会跟着变
row1.getCell(0).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(900));
row1.getCell(1).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(2000));
row1.getCell(2).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(900));
row1.getCell(3).getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(2000));
//设置字体样式
//需求是要求 正文用某种字体大小 英文用某种字体大小 某个特殊的内容需要加粗下划线等等
//为了样式的排版 所以我用了表格的形式写入内容 所以字体这块处理我用了很繁琐的方式
//之前查了很多资料 以为能跟execel一样 一次性把表格里所有的字体设置好样式
//但是找了很久都没有找到
//所以还是决定写个方法老老实实的一个单元格一个单元格的赋值
//希望有大佬能教教我有啥更简便的方式
setStyleToFont(row1,0,"宋体",14,"第一行第一列",false,false,false);
setStyleToFont(row1,2,"宋体",14,"第一行第三列",false,false,false);
//因为有很多内容是需要动态添加的 所以这个时候就可以在原来的table后追加行
//也有很多方法可以在行与行之间插入,大家可以去博客里面找
//下面直接createRow就是在表格最后新增一行
XWPFTableRow row2 = table.createRow();
setStyleToFont(row2,0,"宋体",14,"内容1",false,false,false);
setStyleToFont(row2,1,"宋体",14,"内容2",true,true,true);
//合并列
//拿到了最后一行的下标 对新追加的行 进行合并列操作
mergeCellsHorizontal(table, table.getNumberOfRows() - 1, 1, 3);
}
return doc;
}
/***
* 导出word 设置行宽
* @param table
* @param width
*/
private void setTableWidth(XWPFTable table,String width){
CTTbl ttbl = table.getCTTbl();
CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
CTJc cTJc=tblPr.addNewJc();
cTJc.setVal(STJc.Enum.forString("center"));
tblWidth.setW(new BigInteger(width));
tblWidth.setType(STTblWidth.DXA);
}
/**
* 给单元格的文本内容设置字体
* @param row 当前行
* @param cellIndex 列下标
* @param fontFamily 字体风格
* @param fontSize 字体大小
* @param text 写入的内容
* @param bold 是否加粗
* @param italic 是否倾斜
* @param underline 下划线
*/
private void setStyleToFont(XWPFTableRow row,int cellIndex,String fontFamily,int fontSize,String text,boolean bold,boolean italic,boolean underline){
//这里我是根据一个博主发的贴看到的 博主当时用的是row.getCell(0).addParagraph();
//用add会使单元格换行,然后下面评论里面的一个大佬说换成getParagraphs()
//果然大佬说的没错,这样效果很完美
XWPFParagraph pIO = row.getCell(cellIndex).getParagraphs().get(0);
XWPFRun rIO = pIO.createRun();
rIO.setFontFamily(fontFamily);
rIO.setFontSize(fontSize);
rIO.setText(text);
rIO.setItalic(italic);
rIO.setBold(bold);
if(underline) {
rIO.setUnderline(UnderlinePatterns.SINGLE);
}
}
/***
* 合并列
* @param table
* @param row 当前行下标
* @param fromCell 起始列
* @param toCell 终止列
*/
private 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);
}
}
}
大概的一个内容就是这个样子
写完这篇文章之后才发现原来这次导出使用到的资料也就这么一点点
但从HWPFDocument找到XWPFDocument的资料再到一次次测试效果 估计找了我有一两天的时间
在搜索过程中老是找不到自己想要的效果的关键字
不过也学会了从另一角度解决问题 还测试过了很多类似的导出效果 还是一笔收获
主要参考文章:
https://blog.csdn.net/zhouseawater/article/details/54289495 (创建表格)
https://blog.csdn.net/qq_37660154/article/details/77148198 (单元格合并)
因为需求最近写了一个word的导出
身为菜鸟的我为了写出效果找资料找的我脑瓜子疼
终于写完了我就过来记录一波
第一次写博客 有点小兴奋 给自己留个纪念
最开始是用的 HWPFDocument 这个导出的是2003版本 客户需求
但是随着客户需求的改变 需要操作的内容难度也跟着增大
网上关于HWPFDocument版本的例子真的是少之又少 于是经理帮我联系了一下客户那边
我终于可以换成XWPFDocument 2007的版本来写了!!!这一抓一大把的例子啊!!鸡冻!!!
首先还得感谢这些大佬们分享的资料~~~~
补充
关于字体下划线样式(看api写样式真是痛并快乐着- -)
http://poi.apache.org/apidocs/org/apache/poi/xwpf/usermodel/UnderlinePatterns.html
转载请标明出处~~~