admin 管理员组文章数量: 887007
1.word结构
参考:java通过poi解析word入门_java poi word-CSDN博客
word文档与xml关系_word文件是xml吧-CSDN博客
word的主体结构是包括xml和一些的压缩文件,解压后的目录类似为:
主体是document.xml。
用poi框架操作word文档,类似dom编程。但是编程较繁琐,最好有一个初始word模板。
2.word文档基本标签操作
maven包:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
这里只有基本操作,并没有对api深人了解。
2.1 word文档结构参考
文档内容
大致结构
文档由段落(XWPFParagraph)、表格(XWPFTable)、引注(XWPFSDT)组成的,表格中包含行(Row),行包含单元格(Cell)。cell有能包含表格和段落。所以文档是树结构。
2.2 document和body
有一个document标签和body标签。内容都在body标签中。
可能会有的需求:将多个word文档合并。底层也就是将多个文档的body标签里的内容合并。
目前还未找到好的解决办法。解决思路估计是将body标签中各个元素拷贝并添加在一起。
参考:https://stackoverflow/questions/70648296/merge-documents-by-inserting-content-into-a-new-page-using-poi/70700519#70700519
2.3 table
能创XWPFDocument.createTable()建表格,但是没样式。最好能复制一份模板中的表格再添加。
参考代码:
static public XWPFTable copyTable(XWPFDocument document , XWPFTable origin) throws XmlException, IOException {
CTTbl ctTbl = CTTbl.Factory.parse(origin.getCTTbl().newInputStream());
CTBody body = document.getDocument().getBody();
CTTbl ctTbl1 = body.insertNewTbl(body.getTblList().size());//先新建表格关联body
body.setTblArray(body.getTblList().size()-1,ctTbl);
XWPFTable xwpfTable = new XWPFTable(ctTbl1, document);
document.insertTable(document.getBodyElements().size(),xwpfTable);//关联表格
return xwpfTable;
}
这里参考了XWPFDocument.createTable()的写法,最后第二、三行代码如何去掉似乎也不影响生成word的内容?但可能无法取到封装类XWPFTable ,也就无法对表格进行操作,如创建行。
2.4 row
能调用table.createRow()创建行,但没样式。实际情况一个会在某一行下面创建样式一样的新行。需要注意需要先设置行内容,再调用table.addRow(newRow,pos+1)才能生效
SpringBoot操作XWPFTable(2)创建行和列 – 每天进步一点点
参考代码:
static public XWPFTableRow createNewRowNext(XWPFTable table,XWPFTable module, int pos){
try {
CTRow ctrow = CTRow.Factory.parse(module.getRow(pos).getCtRow().newInputStream());
XWPFTableRow newRow = new XWPFTableRow(ctrow, table);
// table.addRow(newRow,pos+1);//添加内容之后再add
return newRow;
} catch (XmlException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
2.5 cell
cell中能添加多个段落,多个图片等类型。查看XWPFTableCell.setText源码发现,要在cell添加文本,必须至少有一个段落(paragraph)。
参考代码:
清空文本,并添加新内容
static public void setCellText(XWPFTableCell cell,String text) {
if(text==null){
text="";
}
//清空所有段落
List<XWPFParagraph> paragraphs = cell.getParagraphs();
if(paragraphs.size()==0){
cell.setText(text);
}else{
//删除单元格中的所有段落
for (int i = 1; i < paragraphs.size();i++ ) {
cell.removeParagraph(i);
}
List<XWPFRun> runs = paragraphs.get(0).getRuns();
if(runs.size()>0){
for(int i=1;i<runs.size();i++){
paragraphs.get(0).removeRun(i);
}
XWPFRun xwpfRun = paragraphs.get(0).getRuns().get(0);
xwpfRun.setText(text,0);
}else{
cell.setText(text);
}
}
}
创建图片
static public void addPicInCell(InputStream inputStream, String imgPath, XWPFTableCell cell) throws IOException, InvalidFormatException {
XWPFParagraph xwpfParagraph1 = cell.getParagraphs().get(0);
xwpfParagraph1.setAlignment(ParagraphAlignment.CENTER);
XWPFRun cellRun1 = xwpfParagraph1.createRun();
XWPFTableRow row = cell.getTableRow();
XWPFTable table = row.getTable();
int left = table.getCellMarginLeft();
int right = table.getCellMarginRight();
int top = table.getCellMarginTop();
int bottom = table.getCellMarginBottom();
int[] size = calculateImgSize(inputStream,cell.getWidth()-left-right,row.getHeight()-top-bottom);
cellRun1.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_JPEG, imgPath, (size[0])*635, (size[1])*635);
}
这里设置了图片自适应单元格尺寸,需要设置内边距。
2.6 paragraph
段落(paragraph)能添加图片,文本,换行,下一页。
对应的xml格式参考:
<w:p>
<w:r>
<w:t>11111111111111111111111111111</w:t>
<w:br w:type="page"/>
<w:t>22222222222222222222222222</w:t>
</w:r>
<w:r/>
<w:r/>
<w:r>
<w:t>hhhhhhhhhhhhhhhhhhhhhhhhh</w:t>
</w:r>
</w:p>
<w:p>
<w:r>
<w:t>kkkkkkkkkkkkkkkkkkkkkkk</w:t>
</w:r>
</w:p>
设置下一页代码参考:
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run1 = paragraph.createRun();
run1.addBreak(BreakType.PAGE);
3.工具类
package com.example20221209.demo.util;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author yaoct
* @date 2024/10/30 15:30
* @description:
*/
public class WordPoiUtil {
//在下一行添加一行,样式与前一行相同
static public XWPFTableRow createNewRowNext(XWPFTable table, int pos){
try {
CTRow ctrow = CTRow.Factory.parse(table.getRow(pos).getCtRow().newInputStream());
XWPFTableRow newRow = new XWPFTableRow(ctrow, table);
// table.addRow(newRow,pos+1);//添加内容之后再add
return newRow;
} catch (XmlException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//在下一行添加一行,样式与前一行相同
static public XWPFTableRow createNewRowNext(XWPFTable table,XWPFTable module, int pos){
try {
CTRow ctrow = CTRow.Factory.parse(module.getRow(pos).getCtRow().newInputStream());
XWPFTableRow newRow = new XWPFTableRow(ctrow, table);
// table.addRow(newRow,pos+1);//添加内容之后再add
return newRow;
} catch (XmlException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static public void addPicInCell(InputStream inputStream, String imgPath, XWPFTableCell cell) throws IOException, InvalidFormatException {
XWPFParagraph xwpfParagraph1 = cell.getParagraphs().get(0);
xwpfParagraph1.setAlignment(ParagraphAlignment.CENTER);
XWPFRun cellRun1 = xwpfParagraph1.createRun();
XWPFTableRow row = cell.getTableRow();
XWPFTable table = row.getTable();
int left = table.getCellMarginLeft();
int right = table.getCellMarginRight();
int top = table.getCellMarginTop();
int bottom = table.getCellMarginBottom();
int[] size = calculateImgSize(inputStream,cell.getWidth()-left-right,row.getHeight()-top-bottom);
cellRun1.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_JPEG, imgPath, (size[0])* Units.EMU_PER_DXA, (size[1])*Units.EMU_PER_DXA);
}
//适配图片尺寸
private static int[] calculateImgSize(InputStream inputStream, int width, int high) {
//TODO
return new int[]{width,high};
}
static public XWPFTable copyTableNextPage(XWPFDocument document , XWPFTable origin) throws XmlException, IOException {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run1 = paragraph.createRun();
run1.addBreak(BreakType.PAGE);
CTTbl ctTbl = CTTbl.Factory.parse(origin.getCTTbl().newInputStream());
CTBody body = document.getDocument().getBody();
CTTbl ctTbl1 = body.insertNewTbl(body.getTblList().size());//先新建表格关联body
body.setTblArray(body.getTblList().size()-1,ctTbl);
XWPFTable xwpfTable = new XWPFTable(ctTbl1, document);
document.insertTable(document.getBodyElements().size(),xwpfTable);//关联表格
return xwpfTable;
}
static public void nextPage(XWPFDocument document) throws XmlException, IOException {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run1 = paragraph.createRun();
run1.addBreak(BreakType.PAGE);
}
static public XWPFTable copyTable(XWPFDocument document , XWPFTable origin) throws XmlException, IOException {
CTTbl ctTbl = CTTbl.Factory.parse(origin.getCTTbl().newInputStream());
CTBody body = document.getDocument().getBody();
CTTbl ctTbl1 = body.insertNewTbl(body.getTblList().size());//先新建表格关联body
body.setTblArray(body.getTblList().size()-1,ctTbl);
XWPFTable xwpfTable = new XWPFTable(ctTbl1, document);
document.insertTable(document.getBodyElements().size(),xwpfTable);//关联表格
return xwpfTable;
}
static public void setCellText(XWPFTableCell cell,String text) {
if(text==null){
text="";
}
//清空所有段落
List<XWPFParagraph> paragraphs = cell.getParagraphs();
if(paragraphs.size()==0){
cell.setText(text);
}else{
//删除单元格中的所有段落
for (int i = 1; i < paragraphs.size();i++ ) {
cell.removeParagraph(i);
}
List<XWPFRun> runs = paragraphs.get(0).getRuns();
if(runs.size()>0){
for(int i=1;i<runs.size();i++){
paragraphs.get(0).removeRun(i);
}
XWPFRun xwpfRun = paragraphs.get(0).getRuns().get(0);
xwpfRun.setText(text,0);
}else{
cell.setText(text);
}
}
}
/**
* @Description: 跨列合并
*/
static public 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);
}
}
}
/**
* @Description: 跨行合并
* http://stackoverflow/questions/24907541/row-span-with-xwpftable
*/
static public 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);
}
}
}
/**
* 不完善
* @param module
* @param merge
* @throws XmlException
* @throws IOException
*/
static public void copyModule(XWPFDocument module,XWPFDocument merge) throws XmlException, IOException {
List<IBodyElement> bodyElements = module.getBodyElements();
for(int i=0;i<3;i++){
for (IBodyElement bodyElement : bodyElements) {
if(bodyElement instanceof XWPFParagraph){
XWPFParagraph paragraph=(XWPFParagraph)bodyElement;
CTP ctp = CTP.Factory.parse(paragraph.getCTP().newInputStream());
CTBody body = merge.getDocument().getBody();
body.addNewP();
body.setPArray(body.getPList().size()-1,ctp);
// CTP ctp1 = body.insertNewP(body.getPList().size());//先新建段落关联body
// body.setPArray(body.getPList().size()-1,ctp);
// XWPFParagraph paragraph1 = new XWPFParagraph(ctp1, merge);
merge.createParagraph();
// merge.setParagraph(paragraph1,merge.getBodyElements().size()-1);
}else if(bodyElement instanceof XWPFTable){
XWPFTable table=(XWPFTable)bodyElement;
CTTbl ctTbl = CTTbl.Factory.parse(table.getCTTbl().newInputStream());
CTBody body = merge.getDocument().getBody();
CTTbl ctTbl1 = body.insertNewTbl(body.getTblList().size());//先新建表格关联body
body.setTblArray(body.getTblList().size()-1,ctTbl);
XWPFTable xwpfTable = new XWPFTable(ctTbl1, merge);
merge.insertTable(merge.getBodyElements().size(),xwpfTable);//关联表格
}else if(bodyElement instanceof XWPFSDT){
XWPFSDT sdt=(XWPFSDT)bodyElement;
// CTSdtBlock.Factory.parse();
CTBody body = merge.getDocument().getBody();
// body.insertNewSdt(body.getSdtList().size()-1);
// body.setSdtArray(body.getSdtList().size()-1,ctTbl1);
// body.insertNewSdt()
}
}
//下一页
// XWPFParagraph paragraph = merge.createParagraph();
// XWPFRun run1 = paragraph.createRun();
// run1.addBreak(BreakType.PAGE);
}
}
}
参考:
https://stackoverflow/questions/70648296/merge-documents-by-inserting-content-into-a-new-page-using-poi/70700519#70700519
SpringBoot操作XWPFTable(2)创建行和列 – 每天进步一点点
POI:对Word的基本操作_poi操作word-CSDN博客
java通过poi解析word入门_java poi word-CSDN博客
版权声明:本文标题:word poi基本操作记录 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1733521241h1602022.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论