1. 概述
在本文中,我们将重点介绍如何使用docx4j库创建.docx文档。
Docx4j是一个用于创建和操作Office OpenXML文件的Java库-这意味着它只能处理.docx文件类型,而旧版本的Microsoft Word使用.doc扩展名(二进制文件)。
请注意,Microsoft Office从2007版开始支持OpenXML格式。
2. Maven设置
要开始使用docx4j,我们需要在pom.xml中添加所需的依赖:
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>6.1.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>
可以在Maven Central中查找最新的依赖版本。
需要JAXB依赖,因为Docx4j在后台使用这个库来编组/解组docx文件中的XML部分。
3. 创建Docx文件文档
3.1 文本元素和样式
让我们首先看看如何创建一个简单的docx文件–其中包含一个文本段落:
WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage();
MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart();
mainDocumentPart.addStyledParagraphOfText("Title", "Hello World!");
mainDocumentPart.addParagraphOfText("Welcome To Baeldung");
File exportFile = new File("welcome.docx");
wordPackage.save(exportFile);
以下是生成的welcome.docx文件:
要创建新文档,我们必须使用WordprocessingMLPackage,它代表OpenXML格式的docx文件,而MainDocumentPart类则包含主document.xml部分的表示。
为了弄清楚,让我们解压welcome.docx文件,然后打开word/document.xml文件来查看XML表示形式:
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="Title"/>
</w:pPr>
<w:r>
<w:t>Hello World!</w:t>
</w:r>
</w:p>
<w:p>
<w:r>
<w:t>Welcome To Baeldung!</w:t>
</w:r>
</w:p>
</w:body>
我们可以看到,每个句子都由段落(p)内的一串文本(t)表示(r),这就是addParagraphOfText()方法的用途。
addStyledParagraphOfText()所做的比这稍微多一点;它创建一个段落属性(pPr),其中包含要应用于段落的样式。
简而言之,段落声明单独的运行,并且每个运行包含一些文本元素:
为了创建美观的文档,我们需要完全控制这些元素(段落、运行和文本)。
那么,让我们来了解如何使用runProperties(RPr)对象来样式化化我们的内容:
ObjectFactory factory = Context.getWmlObjectFactory();
P p = factory.createP();
R r = factory.createR();
Text t = factory.createText();
t.setValue("Welcome To Baeldung");
r.getContent().add(t);
p.getContent().add(r);
RPr rpr = factory.createRPr();
BooleanDefaultTrue b = new BooleanDefaultTrue();
rpr.setB(b);
rpr.setI(b);
rpr.setCaps(b);
Color green = factory.createColor();
green.setVal("green");
rpr.setColor(green);
r.setRPr(rpr);
mainDocumentPart.getContent().add(p);
File exportFile = new File("welcome.docx");
wordPackage.save(exportFile);
结果如下:
在我们分别使用createP()、createR()和createText()创建段落、运行和文本元素之后,我们声明了一个新的runProperties对象(RPr)来为文本元素添加一些样式。
rpr对象用于设置格式属性、粗体(B)、斜体(I)和大写(Caps),这些属性使用setRPr()方法应用于文本运行。
3.2 使用图像
Docx4j提供了一种向Word文档添加图像的简单方法:
File image = new File("image.jpg" );
byte[] fileContent = Files.readAllBytes(image.toPath());
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage
.createImagePart(wordPackage, fileContent);
Inline inline = imagePart.createImageInline("Baeldung Image (filename hint)", "Alt Text", 1, 2, false);
P Imageparagraph = addImageToParagraph(inline);
mainDocumentPart.getContent().add(Imageparagraph);
addImageToParagraph()方法的实现如下:
private static P addImageToParagraph(Inline inline) {
ObjectFactory factory = new ObjectFactory();
P p = factory.createP();
R r = factory.createR();
p.getContent().add(r);
Drawing drawing = factory.createDrawing();
r.getContent().add(drawing);
drawing.getAnchorOrInline().add(inline);
return p;
}
首先,我们创建了包含要添加到主文档部分的图像的文件,然后,我们将表示图像的字节数组与wordMLPackage对象链接起来。
一旦创建了图像部分,我们需要使用createImageInline()方法创建一个Inline对象。
addImageToParagraph()方法将Inline对象嵌入到Drawing中,以便可以将其添加到运行中。
最后,像文本段落一样,包含图像的段落被添加到mainDocumentPart。
最终的文档结果如下:
3.3 创建表
Docx4j还可以很容易地操作表格(Tbl)、行(Tr)和列(Tc)。
让我们看看如何创建一个3 × 3表格并向其中添加一些内容:
int writableWidthTwips = wordPackage.getDocumentModel()
.getSections().get(0).getPageDimensions().getWritableWidthTwips();
int columnNumber = 3;
Tbl tbl = TblFactory.createTable(3, 3, writableWidthTwips/columnNumber);
List<Object> rows = tbl.getContent();
for (Object row : rows) {
Tr tr = (Tr) row;
List<Object> cells = tr.getContent();
for(Object cell : cells) {
Tc td = (Tc) cell;
td.getContent().add(p);
}
}
给定一些行和列,createTable()方法创建一个新的Tbl对象,第三个参数指的是以缇为单位的列宽(这是一个距离测量-1/1440英寸)。
一旦创建,我们就可以迭代tbl对象的内容,并将Paragraph对象添加到每个单元格中。
让我们看看最终的结果是什么样的:
4. 读取Docx文件文档
现在我们已经了解了如何使用Docx4j创建文档,让我们看看如何读取现有的docx文件并打印其内容:
File doc = new File("helloWorld.docx");
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
.load(doc);
MainDocumentPart mainDocumentPart = wordMLPackage
.getMainDocumentPart();
String textNodesXPath = "//w:t";
List<Object> textNodes= mainDocumentPart
.getJAXBNodesViaXPath(textNodesXPath, true);
for (Object obj : textNodes) {
Text text = (Text) ((JAXBElement) obj).getValue();
String textValue = text.getValue();
System.out.println(textValue);
}
在此示例中,我们使用load()方法基于现有的helloWorld.docx文件创建了一个WordprocessingMLPackage对象。
之后,我们使用XPath表达式(//w:t)从主文档部分获取所有文本节点。
getJAXBNodesViaXPath()方法返回JAXBElement对象的列表。
结果,mainDocumentPart对象内的所有文本元素都打印在控制台中。
请注意,我们始终可以解压缩我们的docx文件以更好地理解XML结构,这有助于分析问题并更好地了解如何解决这些问题。
5. 总结
在本文中,我们了解了Docx4j如何更轻松地对MSWord文档执行复杂操作,例如创建段落、表格、文档部分和添加图像。
Post Directory
