XWPFDocument创建和读取Office Word文档基础篇(一)

参考API:http://poi.apache.org/apidocs/org/apache/poi/xwpf/usermodel/XWPFDocument.html

主要参考文章1:http://www.cnblogs.com/Springmoon-venn/p/5494602.html

主要参考文章2:http://elim.iteye.com/blog/2049110

主要参考文章3:http://doc.okbase.net/oh_Maxy/archive/154764.html

 

 

建议大家使用office word来创建文档。(wps和word结构有些不一样)

 

IBodyElement -------------------迭代器(段落和表格)

XWPFComment -------------------评论(个人理解应该是批注)

XWPFSDT

XWPFFooter -------------------页脚

XWPFFootnotes -------------------脚注

XWPFHeader -------------------页眉

XWPFHyperlink -------------------超链接

XWPFNumbering -------------------编号(我也不知是啥...)

XWPFParagraph -------------------段落

XWPFPictureData -------------------图片

XWPFStyles -------------------样式(设置多级标题的时候用)

XWPFTable -------------------表格

 

1、正文段落

一个文档包含多个段落,一个段落包含多个Runs,一个Runs包含多个Run,Run是文档的最小单元

获取所有段落:List<XWPFParagraph> paragraphs = word.getParagraphs();

获取一个段落中的所有Runs:List<XWPFRun> xwpfRuns = xwpfParagraph.getRuns();

获取一个Runs中的一个Run:XWPFRun run = xwpfRuns.get(index);

 

XWPFRun--代表具有相同属性的一段文本

 

 

2、正文表格

一个文档包含多个表格,一个表格包含多行,一行包含多列(格),每一格的内容相当于一个完整的文档

获取所有表格:List<XWPFTable> xwpfTables = doc.getTables();

获取一个表格中的所有行:List<XWPFTableRow> xwpfTableRows = xwpfTable.getRows();

获取一行中的所有列:List<XWPFTableCell> xwpfTableCells = xwpfTableRow.getTableCells();

获取一格里的内容:List<XWPFParagraph> paragraphs = xwpfTableCell.getParagraphs();

之后和正文段落一样

 

 

注:

  1. 表格的一格相当于一个完整的docx文档,只是没有页眉和页脚。里面可以有表格,使用xwpfTableCell.getTables()获取,and so on
  2. 在poi文档中段落和表格是完全分开的,如果在两个段落中有一个表格,在poi中是没办法确定表格在段落中间的。(当然除非你本来知道了,这句是废话)。只有文档的格式固定,才能正确的得到文档的结构

 

个人理解:我不能确定表格所处的位置(第一个段落后面 ,还是第二个段落后面...)

 

 

3、页眉:

一个文档可以有多个页眉,页眉里面可以包含段落和表格

获取文档的页眉:List<XWPFHeader> headerList = doc.getHeaderList();

获取页眉里的所有段落:List<XWPFParagraph> paras = header.getParagraphs();

获取页眉里的所有表格:List<XWPFTable> tables = header.getTables();

之后就一样了

4、页脚:

页脚和页眉基本类似,可以获取表示页数的角标

 

 

 

言归正传-------干货:

1、通过XWPFDocument读:段落+表格

 

a、获取文档的所有段落

InputStream is = new FileInputStream("D:\\table.docx");  
XWPFDocument doc = new XWPFDocument(is);  
List<XWPFParagraph> paras = doc.getParagraphs(); 

 

获取段落内容

for (XWPFParagraph para : paras) {  
    //当前段落的属性  
//CTPPr pr = para.getCTP().getPPr();  
System.out.println(para.getText());  
} 

b、获取文档中所有的表格  

List<XWPFTable> tables = doc.getTables();  
List<XWPFTableRow> rows;  
List<XWPFTableCell> cells;  

for (XWPFTable table : tables) {  
    //表格属性  
    CTTblPr pr = table.getCTTbl().getTblPr();  
    //获取表格对应的行  
    rows = table.getRows();  
    for (XWPFTableRow row : rows) {  
        //获取行对应的单元格  
        cells = row.getTableCells();  
        for (XWPFTableCell cell : cells) {  
            System.out.println(cell.getText());;  
        }  
    }  
}

2、XWPFDocument生成word

 

直接new一个空的XWPFDocument,之后再往这个XWPFDocument里面填充内容,然后再把它写入到对应的输出流中。

新建一个文档

XWPFDocument doc = new XWPFDocument();
//创建一个段落
XWPFParagraph para = doc.createParagraph();
 
//一个XWPFRun代表具有相同属性的一个区域:一段文本
XWPFRun run = para.createRun();
run.setBold(true); //加粗
run.setText("加粗的内容");
run = para.createRun();
run.setColor("FF0000");
run.setText("红色的字。");
OutputStream os = new FileOutputStream("D:\\simpleWrite.docx");
//把doc输出到输出流
doc.write(os);
this.close(os);

新建一个表格


//XWPFDocument doc = new XWPFDocument();  
//创建一个5行5列的表格  
XWPFTable table = doc.createTable(5, 5);  
//这里增加的列原本初始化创建的那5行在通过getTableCells()方法获取时获取不到,但通过row新增的就可以。  
//table.addNewCol(); //给表格增加一列,变成6列  
table.createRow(); //给表格新增一行,变成6行  
List<XWPFTableRow> rows = table.getRows();  
//表格属性  
CTTblPr tablePr = table.getCTTbl().addNewTblPr();  
//表格宽度  
CTTblWidth width = tablePr.addNewTblW();  
width.setW(BigInteger.valueOf(8000));  
XWPFTableRow row;  
List<XWPFTableCell> cells;  
XWPFTableCell cell;  
int rowSize = rows.size();  
int cellSize;  
for (int i=0; i<rowSize; i++) {  
 row = rows.get(i);  
 //新增单元格  
 row.addNewTableCell();  
 //设置行的高度  
 row.setHeight(500);  
 //行属性  
//CTTrPr rowPr = row.getCtRow().addNewTrPr();  
 //这种方式是可以获取到新增的cell的。  
//List<CTTc> list = row.getCtRow().getTcList();  
 cells = row.getTableCells();  
 cellSize = cells.size();  
 for (int j=0; j<cellSize; j++) {  
    cell = cells.get(j);  
    if ((i+j)%2==0) {  
        //设置单元格的颜色  
        cell.setColor("ff0000"); //红色  
    } else {  
        cell.setColor("0000ff"); //蓝色  
    }  
    //单元格属性  
    CTTcPr cellPr = cell.getCTTc().addNewTcPr();  
    cellPr.addNewVAlign().setVal(STVerticalJc.CENTER);  
    if (j == 3) {  
        //设置宽度  
        cellPr.addNewTcW().setW(BigInteger.valueOf(3000));  
    }  
    cell.setText(i + ", " + j);  
 }
}  
//文件不存在时会自动创建  
OutputStream os = new FileOutputStream("D:\\table.docx");  
//写入文件  
doc.write(os);  
this.close(os); 

段落内容替换

 

/** 
* 替换段落里面的变量 
* @param para 要替换的段落 
* @param params 参数 
*/  
private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {  
  List<XWPFRun> runs;  
  Matcher matcher;  
  if (this.matcher(para.getParagraphText()).find()) {  
     runs = para.getRuns();  
     for (int i=0; i<runs.size(); i++) {  
        XWPFRun run = runs.get(i);  
        String runText = run.toString();  
        matcher = this.matcher(runText);  
        if (matcher.find()) {  
            while ((matcher = this.matcher(runText)).find()) {  
               runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));  
            }  
            //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,  
            //所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。  
            para.removeRun(i);  
            para.insertNewRun(i).setText(runText);  
        }  
     }  
  }  
}   

直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。

//抽取 word docx文件中的图片

String path ="D://abc.docx";  
File file = new File(path);  
try {  
  FileInputStream fis = new FileInputStream(file);  
  XWPFDocument document = new XWPFDocument(fis);  
  XWPFWordExtractor xwpfWordExtractor = new XWPFWordExtractor(document);  
  String text = xwpfWordExtractor.getText();  
  System.out.println(text);  
  List<XWPFPictureData> picList = document.getAllPictures();  
  for (XWPFPictureData pic : picList) {  
    System.out.println(pic.getPictureType() + file.separator + pic.suggestFileExtension()  
        +file.separator+pic.getFileName());  
    byte[] bytev = pic.getData();  
    FileOutputStream fos = new FileOutputStream("D:\\abc\\docxImage\\"+pic.getFileName());   
    fos.write(bytev);  
  }  
  fis.close();  
} catch (IOException e) {  
  e.printStackTrace();  
}  
}  

多级标题结构

/**
 * 自定义样式方式写word,参考statckoverflow的源码
 * 
 * @throws IOException
 */
public static void writeSimpleDocxFile() throws IOException {
    XWPFDocument docxDocument = new XWPFDocument();

    // 老外自定义了一个名字,中文版的最好还是按照word给的标题名来,否则级别上可能会乱
    addCustomHeadingStyle(docxDocument, "标题 1", 1);
    addCustomHeadingStyle(docxDocument, "标题 2", 2);

    // 标题1
    XWPFParagraph paragraph = docxDocument.createParagraph();
    XWPFRun run = paragraph.createRun();
    run.setText("标题 1");
    paragraph.setStyle("标题 1");

    // 标题2
    XWPFParagraph paragraph2 = docxDocument.createParagraph();
    XWPFRun run2 = paragraph2.createRun();
    run2.setText("标题 2");
    paragraph2.setStyle("标题 2");

    // 正文
    XWPFParagraph paragraphX = docxDocument.createParagraph();
    XWPFRun runX = paragraphX.createRun();
    runX.setText("正文");

    // word写入到文件
    FileOutputStream fos = new FileOutputStream("D:/myDoc2.docx");
    docxDocument.write(fos);
    fos.close();
}

/**
 * 增加自定义标题样式。这里用的是stackoverflow的源码
 * 
 * @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);

}
 
  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: xwpfdocument是Apache POI库中的一个类,用于读取和操作Microsoft Word 2007及以上版本的.docx文件。它提供了一种方便的方式来读取Word文档中的内容,包括文本、表格、图片等。使用xwpfdocument可以轻松地将Word文档中的内容提取出来,并进行进一步的处理和分析。 ### 回答2: xwpfdocument是Apache POI库中的一个类,用于读取Microsoft Word的.docx文件。通过xwpfdocument,我们可以将Word文档转换为Java代码中的数据结构,并对文档内容进行读写操作。 首先,我们需要通过java.io包中的FileInputStream类将Word文档读入内存中。代码示例如下: ``` FileInputStream fis = new FileInputStream(new File("example.docx")); XWPFDocument doc = new XWPFDocument(fis); ``` 从上述代码中可以看到,我们首先创建了一个FileInputStream对象,指定了要读取Word文档的路径。然后,我们将FileInputStream对象传递给XWPFDocument的构造函数,生成一个代表Word文档的XWPFDocument对象。 接下来,我们便可以通过XWPFDocument对象来读取文档内容了。例如,我们可以通过以下代码获取文档中所有的段落: ``` List<XWPFParagraph> paragraphs = doc.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { System.out.println(paragraph.getText()); } ``` 上述代码获取了文档中的所有段落,并通过for循环遍历每一个段落,输出其文本内容。 除了获取文本内容外,我们还可以通过XWPFDocument获取文档中的表格、图片等特殊内容,具体的操作可参考Apache POI的官方文档。 总之,xwpfdocument的作用主要是用于读取Word文档,将文档内容转换为Java的数据结构,方便我们进行读写操作。 ### 回答3: xwpfdocument是Apache POI中的一个类,它提供了读取和写入Microsoft Word的DOCX格式的能力。下面是xwpfdocument读取word的解释和过程。 xwpfdocument读取word的解释: xwpfdocument是用于读取Word文档的一个Java类。这个类可以读取.docx格式的Word文档,解析其中的文字、图片等内容,并以Java对象的形式返回到程序中供开发者使用。 xwpfdocument读取word的过程: 1. 导入需要的库文件 使用xwpfdocument读取word文档需要导入Apache POI的核心库poi.jar、poi-ooxml.jar和poi-ooxml-schemas.jar。 2. 创建xwpfdocument对象,并从文件中读取Word文档 实例化xwpfdocument对象,并通过xwpfdocument对象的构造函数将Word文档的路径传入,将会返回一个读取到的Word文档对象。 FileInputStream fileInputStream = new FileInputStream("F:/Java/wxw.docx"); XWPFDocument xwpfDocument = new XWPFDocument(fileInputStream); 3. 读取Word文档中的内容 通过xwpfdocument对象提供的方法来获取Word文档中的内容。包括段落、文字、图片等信息。 //获取所有的段落 List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { System.out.println(paragraph.getText()); } //获取所有图片 List<XWPFPictureData> pictureDatas = xwpfDocument.getAllPictures(); for (XWPFPictureData pictureData : pictureDatas) { System.out.println(pictureData.getFileName()); byte[] pictureByte = pictureData.getData(); } 4. 关闭文件输入流 使用完毕后使用close方法关闭文件输入流。 fileInputStream.close(); 总之,xwpfdocument读取word是非常简单并且实用的。通过xwpfdocument对象读取Word文档并获取其中的内容,方便快捷地操作Word文档

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值