Apache POI Word - 段落
概述
上一篇中我们讲述了如何创建和保存文档,本篇接着上一篇,讲述如何往文档中添加段落和文字以及如何改变文字的样式。
文档的组成部分
一个文档通常包含一个标题,若干个二级、三级(四级五级。。。如果你愿意的话)标题,每个标题下面通常包含一个或者多个段落,每个段落里面又包含多个文字。
当然文档中还可以包含表格、图片和视频等,这不是本文的内容,这些内容在后续文章中会有说明。
给文档添加段落和文字
创建段落并添加文字:
XWPFParagraph p = doc.createParagraph();
XWPFRun run = p.createRun();
run.setText("this this the text in paragraph");
是不是很简单?但是我觉得还不够简洁,如果 XWPFParagraph 直接有个 addText(String text)
方法是不是更简单?为什么 POI 的 api 要设计一个 Run 对象来承载文字?什么是 Run 呢?
在回答这个问题之前,让我们先创建一个 run.docx 文档,然后在文档中放入如下文字。
然后将文档重命名为 run.zip,解压然后看看 document.xml 文件的内容
从这个 xml 结构是不是看出点什么门道了?POI 的 api 正是和这个 xml 结构保持一致的。<w:p>
是 <w:paragraph>
的缩写,同理 <w:r>
其实应该是 <w:run>
的缩写。<w:rPr>
则是 <w:runProperites>
的缩写。
Run 用来承载具有相同样式的一段文字。由于”This is red text,but this is becomes green.“ 这句话包含了两种样式,因此有两个 Run 对象。
有了上面的铺垫,再看看通过 POI api 来生成这段文字的代码是不是很容易理解?
package net.verytools.tutorial;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import java.io.FileOutputStream;
import java.io.IOException;
public class CreateDoc {
public static void main(String[] args) throws IOException {
XWPFDocument doc = new XWPFDocument();
XWPFParagraph p = doc.createParagraph();
XWPFRun run1 = p.createRun();
run1.setColor("FF0000");
run1.setText("This is red text,");
XWPFRun run2 = p.createRun();
run2.setColor("00FF00");
run2.setText("but this is becomes green.");
// ...
}
}
Run 对象除了可以设置颜色之外,还可以设置字体、字体大小、字体是否加粗等。
// 设置字体大小
run1.setFontSize(16);
// 设置字体
run1.setFontFamily("Arial Black");
// 字体加粗
run1.setBold(true);
段落中换行也是通过 Run 对象实现的
XWPFParagraph p = doc.createParagraph();
XWPFRun run = p.createRun();
run.addBreak(BreakType.TEXT_WRAPPING);
给文档一个标题
标题应该用什么 api 来生成呢? 前面我们提到 docx 文档的本质是一个包含多个 xml 和媒体文件的 zip 文件,那么我们在 docx 文档中插入一个一级标题,然后将 docx 后缀 改成 .zip,解压看看 xml 是不是有所启发呢?
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="2"/>
<w:bidi w:val="0"/>
<w:rPr>
<w:rFonts w:hint="default"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:lang w:val="en-US" w:eastAsia="zh-CN"/>
</w:rPr>
<w:t>This is the title</w:t>
</w:r>
</w:p>
</w:body>
从<w:p>
可以看出标题也是一个段落。从 <w:pStyle w:val="2"/>
可以看出标题应用了一个 id 为 ”2“ 的样式,从 styles.xml 中可以找到 id 为 ”2“ 的样式。
从图中可以看出该样式指定了字体大小为 44、字体加粗且样式的名称为 “heading 1”。<w:basedOn w:val="1"/>
表明该样式基于 id 为 1 的样式。id 为 1 的样式这里就不放图了,该样式中指定了对齐方式为居中对齐。
注意:xml 中的 <w:sz w:val="44"/>
的单位是 half-point(半点),因此字体大小实际为 22pt。
样式的好处是复用,我们可以在文档的多个部分应用同一个样式。如何使用 POI 生成样式呢?这个问题将在后续的文章中说明。暂时我们不使用样式,通过设置合适的字体大小并加粗字体来模拟标题。
try (XWPFDocument doc = new XWPFDocument()) {
try (FileOutputStream out = new FileOutputStream("D:\\tmp\\simpledoc.docx")) {
XWPFParagraph p = doc.createParagraph();
// 居中对齐
p.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = p.createRun();
// 加粗
run.setBold(true);
// 字体大小为 44 half-point
run.setFontSize(22);
run.setFontFamily("Calibri");
run.setText("This is title");
doc.write(out);
}
}
虽然我们没有使用样式,但是我们生成的标题和使用 Office 软件制作的一级标题的样式看上去基本相同,不过需要说明的这个只是显示效果近似而已,标题还有一个重要的特性便是大纲级别。这一点我们会在后续讲到样式的时候另行说明。
温馨提示:反馈需要登录