java 使用 POI 操作 XWPFDocumen 创建和读取 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 ------------------- 表格
二、正文段落
一个文档包含多个段落,一个段落包含多个 Runs,一个 Runs 包含多个 Run,Run 是文档的最小单元
获取所有段落:List paragraphs = word.getParagraphs();
获取一个段落中的所有 Runs:List xwpfRuns = xwpfParagraph.getRuns();
获取一个 Runs 中的一个 Run:XWPFRun run = xwpfRuns.get(index);
XWPFRun-- 代表具有相同属性的一段文本
三、正文表格
一个文档包含多个表格,一个表格包含多行,一行包含多列(格),每一格的内容相当于一个完整的文档
获取所有表格:List xwpfTables = doc.getTables();
获取一个表格中的所有行:List xwpfTableRows = xwpfTable.getRows();
获取一行中的所有列:List xwpfTableCells = xwpfTableRow.getTableCells();
获取一格里的内容:List paragraphs = xwpfTableCell.getParagraphs();
之后和正文段落一样
注:
- 表格的一格相当于一个完整的 docx 文档,只是没有页眉和页脚。里面可以有表格,使用 xwpfTableCell.getTables() 获取,and so on
- 在 poi 文档中段落和表格是完全分开的,如果在两个段落中有一个表格,在 poi 中是没办法确定表格在段落中间的。(当然除非你本来知道了,这句是废话)。只有文档的格式固定,才能正确的得到文档的结构
个人理解:我不能确定表格所处的位置(第一个段落后面 ,还是第二个段落后面...)
3、页眉:
一个文档可以有多个页眉, 页眉里面可以包含段落和表格
获取文档的页眉:List headerList = doc.getHeaderList();
获取页眉里的所有段落:List paras = header.getParagraphs();
获取页眉里的所有表格:List tables = header.getTables();
之后就一样了
四、页脚:
页脚和页眉基本类似,可以获取表示页数的角标
言归正传 ------- 干货:
五、通过 XWPFDocument 读:段落 + 表格
a、获取文档的所有段落
InputStream is = new FileInputStream("D:\table.docx");
XWPFDocument doc = new XWPFDocument(is);
List paras = doc.getParagraphs();
获取段落内容
for (XWPFParagraph para : paras) {// 当前段落的属性 //CTPPr pr = para.getCTP().getPPr();
System.out.println(para.getText());
}
b、获取文档中所有的表格
List tables = doc.getTables(); List rows; List 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());;}} }
六、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 rows = table.getRows(); // 表格属性 CTTblPr tablePr = table.getCTTbl().addNewTblPr(); // 表格宽度 CTTblWidth width = tablePr.addNewTblW(); width.setW(BigInteger.valueOf(8000));XWPFTableRow row;List cells;XWPFTableCell cell; int rowSize = rows.size(); int cellSize; for (int i=0; i) {row = rows.get(i); // 新增单元格 row.addNewTableCell(); // 设置行的高度 row.setHeight(500); // 行属性 //CTTrPr rowPr = row.getCtRow().addNewTrPr(); // 这种方式是可以获取到新增的 cell 的。 //List list = row.getCtRow().getTcList(); cells = row.getTableCells();cellSize = cells.size(); for (int j=0; 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 params) {List runs;Matcher matcher; if (this.matcher(para.getParagraphText()).find()) {runs = para.getRuns(); for (int i=0; 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 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); // 标题 1XWPFParagraph paragraph = docxDocument.createParagraph();XWPFRun run = paragraph.createRun();run.setText(" 标题 1");paragraph.setStyle(" 标题 1"); // 标题 2XWPFParagraph 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 barctStyle.setQFormat(onoffnull); // style defines a heading of the given levelCTPPr ppr = CTPPr.Factory.newInstance();ppr.setOutlineLvl(indentNumber);ctStyle.setPPr(ppr);XWPFStyle style = new XWPFStyle(ctStyle); // is a null op if already definedXWPFStyles styles = docxDocument.createStyles();style.setType(STStyleType.PARAGRAPH);styles.addStyle(style);}
创建文本对象
XWPFDocument docxDocument = new XWPFDocument();
创建段落对象
XWPFParagraph paragraphX = docxDocument.createParagraph();
XWPFParagraph 段落属性
//paragraphX.addRun(runX0);//似乎并没有什么卵用 //paragraphX.removeRun(1);//按数组下标删除run(文本) paragraphX.setAlignment(ParagraphAlignment.LEFT);//对齐方式 //paragraphX.setBorderBetween(Borders.LIGHTNING_1);//边界 (但是我设置了好几个值都没有效果) //paragraphX.setFirstLineIndent(100);//首行缩进:-----效果不详 //paragraphX.setFontAlignment(3);//字体对齐方式:1左对齐 2居中3右对齐 //paragraphX.setIndentationFirstLine(567);//首行缩进:567==1厘米 //paragraphX.setIndentationHanging(567);//指定缩进,从父段落的第一行删除,将第一行上的缩进移回到文本流方向的开头。 //paragraphX.setIndentationLeft(2);//-----效果不详 //paragraphX.setIndentationRight(2);//-----效果不详 //paragraphX.setIndentFromLeft(2);//-----效果不详 //paragraphX.setIndentFromRight(2);//-----效果不详 //paragraphX.setNumID(new BigInteger("3"));//设置段落编号-----有效果看不懂(仅仅是整段缩进4个字) //paragraphX.setPageBreak(true);//段前分页 //paragraphX.setSpacingAfter(1);//指定文档中此段最后一行以绝对单位添加的间距。-----效果不详 //paragraphX.setSpacingBeforeLines(2);//指定在该行的第一行中添加行单位之前的间距-----效果不详 //paragraphX.setStyle("标题 3");//段落样式:需要结合addCustomHeadingStyle(docxDocument, "标题 3", 3)配合使用 paragraphX.setVerticalAlignment(TextAlignment.BOTTOM);//文本对齐方式(我猜在 table 里面会有比较明显得到效果) paragraphX.setWordWrapped(true);//这个元素指定一个消费者是否应该突破拉丁语文本超过一行的文本范围,打破单词跨两行(打破字符水平)或移动到以下行字(打破字级)-----(我没看懂: 填个 false 还报异常了)
转载于:https://www.cnblogs.com/mh-study/p/9747945.html
java 使用 POI 操作 XWPFDocumen 创建和读取 Office Word 文档基础篇相关推荐
- Java使用POI生成饼状图导出到word文档(饼状图)
本篇文章主要介绍,如何使用Apache POI组件生成饼状图导出到word文档中,具体步骤看下文. 一.实现效果 Java使用POI技术生成饼状图导出到word文档中,最终生成的饼状图如下所示: 二. ...
- php读取word文件并解析图片,PHP读取office word文档内容及图片
PHP读取word文档里的文字及图片,并保存 一.composer安装phpWord composer require phpoffice/phpword 二.phpWord 读取 docx 文档(注 ...
- 【操作word】Java + POI导出富文本的内容到word文档
这周工作中,遇到一个需求是需要将数据库中富文本内容导出到word文档里面,于是就采用POI技术实现了一下导出word文档的功能.(word文档是识别html内容的,所以富文本内容也自然能够识别.) 一 ...
- 使用ABAP编程实现对微软Office Word文档的操作
SAP ABAP里提供了一个标准的类CL_DOCX_DOCUMENT,提供了本地以".docx"结尾的微软Office word文档的读和写操作. 本文介绍了ABAP类CL_DOC ...
- java将后台数据库查询到的数据导出word文档当中
java将后台数据库查询到的数据导出word文档当中 之前项目需求使用Java导出word文档,一直没有进行整理,今天把它进行整理出来,以便以后使用到:下面是导出的word文档. // 前端报告表格 ...
- Java项目中利用Freemarker模板引擎导出--生成Word文档
应邀写的一篇文章:Java项目中利用Freemarker模板引擎导出--生成Word文档 资源下载:https://download.csdn.net/download/weixin_41367523 ...
- Python-docx 模块读写 Word 文档基础(一):创建文档、段落格式、字体格式设置方法
Python-docx 模块读写 Word 文档基础(一):创建文档.段落格式.字体格式设置方法 前言: 1.创建 Word 文档及基础用法: 2.段落格式设置: 3.字体格式设置: 结尾: [Pyt ...
- Python3-word文档操作(八):提取word文档中的图片方式一-利用docx库
1. 简介: 要获取word文档中的图片文件.思路就是先解压,再查找.python中,下面两个库都可以实现这个功能: (1)zip库 (2)docx库 zip库: 上一篇博文已经提过,word本质上也 ...
- java毕业论文_【毕业论文】基于java的博客网站设计与开发毕业论文(word文档)
<[毕业论文]基于java的博客网站设计与开发毕业论文.doc>由会员分享,可免费在线阅读全文,更多与<[毕业论文]基于java的博客网站设计与开发毕业论文(word文档)>相 ...
最新文章
- linux apache配置多线程,linux apache 日志配置
- ASP.NET重用代码技术 - 代码绑定技术
- 遇见BUG(1):都是非时钟专用引脚惹的祸?
- JavaScript 中 void(0) 的含义
- docker-compose command 执行多条指令
- 将EXE安装包重新封装成MSI格式
- python class用法_python原类、类的创建过程与方法
- Python中的字典dict
- Java JDBC篇4——数据库连接池
- Unity MRTK RadialView
- 知其然,知其所以然——ArrayList.add()详解
- Linux/debian/ubuntu/deepin 等系统禁用鼠标中键(滚轮)按下粘贴的方法
- Spark Streaming背压机制
- 微信群骂人违法吗?怎么维权
- week10 day1 JavaScript
- HAL库的串口基础学习(包含串口接收不定长数据的实现)
- 方法: 跳转App Store更新你应用的URL究竟该怎么写
- java的自省机制_JAVA内省(自省)机制 ( Introspector , BeanInfo, PropertyDescriptor )
- NLP学习(二)—中文分词技术
- 项目管理习题——挣钱分析法与成本预算和成本估算