poi操作word⽂档,poi向word插⼊图⽚,poi向word⼊表格,XWPFPara。。。前⾔
因为⼯作任务填充word的模板,之前⽤的最多的是excel。第⼀次操作word,⾯向百度开发,遇到了很多问题,也了很多bolg。百度有很多标题与内容不符的blog, 的有点⼼累,现在做⼀个总结。
版本:5.0.0
在线Api: /apidocs/5.0/
问题总结
1. XWPFRun 分段问题
2. 在指定位置填充表格
3. 在表格⾥⾯插⼊表格
4. 插⼊图⽚
5. 单元格合并
未解决的问题: 在word⾥⾯插⼊附件
解决问题
XWPFRun 分段问题
例如我要替换word⾥⾯的${name}和${year}
在poi分段的时候可能会分成这样的段落
${
nam
e}
${year
}
解决⽅法:
1. ⽹上的解决⽅案是 在text⾥⾯写标记然后在复制粘贴到word
这种⽅法太⿇烦
2. ⽤⼀个临时变量存储标记
XWPFDocument document =new XWPFDocument(in);
List<XWPFParagraph> pars = Paragraphs();
StringBuilder builder;
for(XWPFParagraph pg : pars){
Text().contains("$")){
builder =new StringBuilder();
// 获取分词
List<XWPFRun> runs = pg.getRuns();
boolean start =false;
String text;
for(XWPFRun run : runs){
text = ();
if(text.startsWith("$")){
start =true;
}
if(start){
builder.append(text);
// 清除标记
run.setText("",0);
}
dsWith("}")){
start =false;
// 获取到完整标记
// TODO 业务逻辑
System.out.String());
}
}
}
}
在指定位置插⼊⼀个表格
我在word⾥⾯打了⼀个${table}标记,要在这个地⽅插⼊⼀个表格
··· 到该段落
// ⾸先获取段落游标
XmlCursor cursor = pg.getCTP().newCursor();
// 跳到下⼀⾏
// 然后根据游标插⼊⼀个表格
XWPFTable table = document.insertNewTbl(cursor);
// 创建⾏
XWPFTableRow row = ateRow();
// 创建单元格
XWPFTableCell cell = ateCell();
新插⼊的表格只有⼀⾏⼀列,也就是只有⼀个单元格。并且创建第⼀⾏填充多少格,后续⾏就是多少格,不⽤再创建单元格了在表格⾥⾯插⼊表格
XmlCursor cursor = pg.getCTP().newCursor();
XWPFTable table = document.insertNewTbl(cursor);
// document 插⼊的表格只有⼀⾏⼀格
XWPFTableCell cell = Row(0).getCell(0);
// 添加段落
XWPFParagraph cellPg = cell.addParagraph();
// 创建⼀个⽂本区域
XWPFRun cellRun = ateRun();
cellRun.setText("天青⾊等烟⾬");
// 获取游标
XmlCursor c = cell.addParagraph().getCTP().newCursor();
// 游标下移
// 插⼊表格
XWPFTable cellTable = cell.insertNewTbl(c);
// 这个表格第⼀⾏不能使⽤,删除掉
// 填充内容
结果:
这⾥只是做⼀个演⽰,表格⾥⾯插⼊的表格没有边框,需要⼿动设置边框属性。
private static void setBorders(XWPFTable table){
// ⾃动宽度
cell.setWidthType(TableWidthType.AUTO);
CTTcBorders borders =null;
CTTc().addNewTcPr().getTcBorders()==null){
borders = CTTc().addNewTcPr().addNewTcBorders();
}
// 上下左右
setBorder(borders.addNewTop());
setBorder(borders.addNewBottom());
setBorder(borders.addNewLeft());
setBorder(borders.addNewRight());
});
});
}
private static void setBorder(CTBorder border){
// 设置单实线
border.setVal(STBorder.SINGLE);
// 宽度
border.setSz(BigInteger.valueOf(2));
border.setColor("000000");
}
效果:
注意 : 如果在多⾏⾥⾯插⼊多格, 需要填充空值进去,不然导出表格后会有表格属于错误的异常插⼊图⽚
XWPFDocument 有两个插⼊图⽚的⽅法
⼀个是插⼊单张图⽚
⼀个是插⼊多张图⽚
这个是直接添加到word末尾.
要插⼊到指定位置就使⽤XWPFRun#addPicture ⽅法
这个⽅法有5个参数
从左到右:图⽚输⼊流,图⽚类型,图⽚名,宽度,⾼度
try(FileInputStream pic =new FileInputStream("..\图⽚1.png")){
run.addPicture(pic, Document.PICTURE_TYPE_PNG,"图⽚", EMU(100),EMU(100)); }
效果:
表格合并
表格合并有两种⽅式
1. ⼀个是跨⾏,如果是表格已经建好的,会把该表格后⾯单元格"挤"出去.
// XWPFTableCell
2. 设置表格属性
// word跨列合并单元格
public void mergeCellsHorizontal(XWPFTable table,int row,int fromCell,int toCell){ for(int cellIndex = fromCell; cellIndex <= toCell; cellIndex++){
XWPFTableCell cell = Row(row).getCell(cellIndex);
if( cellIndex == fromCell ){
// The first merged cell is set with RESTART merge value
}else{
// Cells which join (merge) the first one, are set with CONTINUE
}
}
}
// word跨⾏并单元格
public void mergeCellsVertically(XWPFTable table,int col,int fromRow,int toRow){ for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++){
XWPFTableCell cell = Row(rowIndex).getCell(col);
if( rowIndex == fromRow ){
// The first merged cell is set with RESTART merge value
}else{
// Cells which join (merge) the first one, are set with CONTINUE
}
}
}
完整代码
package;
import StringUtils;
import Units;
import*;
import CTBorder;
import CTTcBorders;
import CTTcPr;
import STBorder;
import FileInputStream;
import IOException;
import InputStream;
import OutputStream;
import Field;
import BigInteger;
import ArrayList;
import HashMap;
import List;
import Map;
public class WordUtils {
private WordUtils(){
}
/**
* @param input  word模板输⼊流
* @param outPut 输出流
* @param object 数据对象
* @throws IllegalAccessException
*/
public static void export(InputStream input, OutputStream outPut, Object object)throws IllegalAccessException {
Map<String, Object> parameters =new HashMap<>();
getParameters(object, Class(), parameters);
export(input, outPut, parameters);
}
/**
* @param input      word模板输⼊流
* @param outPut    输出流
document有安卓版吗* @param parameters 填充数据Map
*/
public static void export(InputStream input, OutputStream outPut, Map<String, Object> parameters){
try(XWPFDocument document =new XWPFDocument(input)){
// 填充text或者图⽚或者其他
Paragraphs(), parameters);
// 填充表格
fillTable(document, parameters);
document.write(outPut);
}catch(IOException e){
e.printStackTrace();
}
}
/
**
* 把对象解析成Map,如果是持有其他对象也会解析到map.
* 1,如果去持有的对象有相同名称的filed,会被后⾯的覆盖.
* 2,如果是持有其他对象的集合,现在只处理了数组,List,Map类型的没有进⾏处理
* @param object 数据对象
* @param clazz 数据对象的class
* @param parameters 解析的结果
* @throws IllegalAccessException
*/
private static void getParameters(Object object, Class<?> clazz, Map<String, Object> parameters)throws IllegalAccessException {        Field[] fields = DeclaredFields();
Object value;
for(Field field : fields){
field.setAccessible(true);
value =getValue(field, object);
Type().isArray()){
parsingCollection(field, object, parameters);
}else if(Type())){
parameters.put("${"+ Name()+"}", value);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。