docx4j书签的妙用
docx4j的功能十分的强大,支持对文档进行插入修改等操作。也是正好需要学习docx4j,就写此博客记录一下。目前只能展示一部分代码,有需要可以一起学习一下。
1.在书签处插入图片
2.在书签处插入表格
3.在书签处插入文档
4.API与中文入门指南
需要提前准备一个文档template.docx,放在
系统某个位置底下
内容三部分都要下方加入书签。
1.在书签处插入图片
核心代码:
import com.digitalgd.offce.gendocument.config.ImageConfig;
import org.docx4j.TraversalUtil;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.finders.RangeFinder;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.org.apache.poi.util.IOUtils;
import org.docx4j.wml.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;
@Service
public class InsertImage {
@Autowired
private ImageConfig imageConfig;
public void insertimage(String templatePath, String targetPath, String bookmarkName, String imagePath)
throws Exception {
// 载入模板文件
WordprocessingMLPackage wPackage = WordprocessingMLPackage.load(new FileInputStream(templatePath));
// 提取正文
MainDocumentPart mainDocumentPart = wPackage.getMainDocumentPart();
Document wmlDoc = (Document) mainDocumentPart.getJaxbElement();
Body body = wmlDoc.getBody();
// 提取正文中所有段落
List<Object> paragraphs = body.getContent();
RangeFinder rt = new RangeFinder(imageConfig.getCbookmark(), imageConfig.getCmarkuprange());
new TraversalUtil(paragraphs, rt);
// 遍历书签
for (CTBookmark bm:rt.getStarts()) {
if (bm.getName().equals(bookmarkName)){
InputStream is = new FileInputStream(imagePath);
byte[] bytes = IOUtils.toByteArray(is);
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wPackage, bytes);
Inline inline = imagePart.createImageInline(null, null, 0,1, false, imageConfig.getMaxwidth());
P p = (P)(bm.getParent());
ObjectFactory factory = new ObjectFactory();
R run = factory.createR();
Drawing drawing = factory.createDrawing();
drawing.getAnchorOrInline().add(inline);
run.getContent().add(drawing);
p.getContent().add(run);
}
}
wPackage.save(new FileOutputStream(targetPath));
}
}
2.在书签处插入表格
核心代码:
import com.digitalgd.offce.gendocument.config.TableConfig;
import org.docx4j.Docx4J;
import org.docx4j.TraversalUtil;
import org.docx4j.finders.RangeFinder;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
@Service
public class InsertTable {
@Autowired
private TableConfig tableConfig;
public void inserttable(String templatePath, String bookmarkName, String targetPath) throws Exception{
// 载入模板文件
WordprocessingMLPackage wPackage = WordprocessingMLPackage.load(new FileInputStream(templatePath));
// 提取正文
MainDocumentPart mainDocumentPart = wPackage.getMainDocumentPart();
Document wmlDoc = (Document) mainDocumentPart.getJaxbElement();
Body body = wmlDoc.getBody();
// 提取正文中所有段落
List<Object> paragraphs = body.getContent();
RangeFinder rt = new RangeFinder(tableConfig.getCbookmark(), tableConfig.getCmarkuprange());
new TraversalUtil(paragraphs, rt);
// 遍历书签
for (CTBookmark bm:rt.getStarts()) {
if (bm.getName().equals(bookmarkName)){
addTable(mainDocumentPart);
}
}
wPackage.save(new FileOutputStream(targetPath));
}
public void filltable(String templatePath, String microServName,String functionDesc,String targetPath) throws Exception{
WordprocessingMLPackage wPackage = WordprocessingMLPackage.load(new FileInputStream(templatePath));
HashMap<String, String> mappings = new HashMap<>();
//构造非循环格子的表格数据
mappings.put("microServName",microServName);
mappings.put("functionDesc",functionDesc);
wPackage.getMainDocumentPart().variableReplace(mappings);
wPackage.save(new FileOutputStream(targetPath));
}
public static void addTable(MainDocumentPart mainDocumentPart) {
ObjectFactory factory = Context.getWmlObjectFactory();
// 0. 创建表格元素
Tbl table = factory.createTbl();
// 1.显示表格的边框
addBorders(table);
// 2.添加表格内容(创建行和列)
for (int i = 0; i < 3; i++) {
Tr tr = factory.createTr();
for (int j = 0; j < 3; j++) {
Tc tc = factory.createTc();
// P p = mainDocumentPart.createParagraphOfText("---row" + i
// + "---column" + j + "---");
// 第二种创建P并设置样式的方法
P p1 = factory.createP();
R r = factory.createR();
Text text = factory.createText();
text.setValue("---row" + i + "---column" + j + "---");
r.getContent().add(text);
p1.getContent().add(r);
// 2.1通过R设置字体加粗等属性
setRStyle(r);
// 2.2设置列宽
if (j == 1) {
setCellWidth(tc, 1250);
} else {
setCellWidth(tc, 2500);
}
tc.getContent().add(p1);
tr.getContent().add(tc);
}
table.getContent().add(tr);
}
// 3.合并单元格
// 3.加表格加到主要内容中
mainDocumentPart.addObject(table);
}
/**
* 设置列宽
*
* @param tc
* @param width
*/
private static void setCellWidth(Tc tc, int width) {
TcPr tableCellProperties = new TcPr();
TblWidth tableWidth = new TblWidth();
tableWidth.setW(BigInteger.valueOf(width));
tableCellProperties.setTcW(tableWidth);
tc.setTcPr(tableCellProperties);
}
/**
* 通过设置R设置表格中属性字体加粗,大小为25
*
* @param
*/
private static void setRStyle(R r) {
// 1.创建一个RPr
RPr rpr = new RPr();
// 2.设置RPr
// 2.1设置字体大小
HpsMeasure size = new HpsMeasure();
size.setVal(new BigInteger("25"));
rpr.setSz(size);
// 2.2设置加粗
BooleanDefaultTrue bold = new BooleanDefaultTrue();
bold.setVal(true);
rpr.setB(bold);
// 3.将RPr设置为R的属性
r.setRPr(rpr);
}
/**
* 设置边框样式
*
* @param table
* 需要设置表格边框的单元格
*/
private static void addBorders(Tbl table) {
table.setTblPr(new TblPr());// 必须设置一个TblPr,否则最后会报空指针异常
CTBorder border = new CTBorder();
border.setColor("auto");
border.setSz(new BigInteger("4"));
border.setSpace(new BigInteger("0"));
border.setVal(STBorder.SINGLE);
TblBorders borders = new TblBorders();
borders.setBottom(border);
borders.setLeft(border);
borders.setRight(border);
borders.setTop(border);
borders.setInsideH(border);
borders.setInsideV(border);
// 获取其内部的TblPr属性设置属性
table.getTblPr().setTblBorders(borders);
}
}
2.在书签处插入文档
核心部分:
/**
*
* @param streams
* @return
* @throws Docx4JException
* @throws IOException
*/
public InputStream doGeneratorDocx(final List<InputStream> streams) throws Docx4JException, IOException {
WordprocessingMLPackage target = null;
final File generated = File.createTempFile(outlineDocConfig.getDocprefix(), outlineDocConfig.getDocsuffix());
int chunkId = 0;
Iterator<InputStream> it = streams.iterator();
while (it.hasNext()) {
InputStream is = it.next();
if ( null != is ) {
if (target == null) {
OutputStream os = new FileOutputStream(generated);
os.write(IOUtils.toByteArray(is));
os.close();
target = WordprocessingMLPackage.load(generated);
} else {
//
Document wmlDoc = (Document) target.getMainDocumentPart().getJaxbElement();
Body body = wmlDoc.getBody();
// 提取正文中所有段落
List<Object> paragraphs = body.getContent();
// 提取书签并创建书签的游标
RangeFinder rt = new RangeFinder(outlineDocConfig.getCbookmark(), outlineDocConfig.getCmarkuprange());
new TraversalUtil(paragraphs, rt);
String bookmarkName = outlineDocConfig.getMarkinterfacedoc();
switch (chunkId){
case 0:
bookmarkName = outlineDocConfig.getMarktable();
break;
default:
bookmarkName = outlineDocConfig.getMarkinterfacedoc();
break;
}
for (CTBookmark bm:rt.getStarts()) {
if (bm.getName().equals(bookmarkName)) {
//
doInsertDocx(target.getMainDocumentPart(), (P) bm.getParent(), IOUtils.toByteArray(is), chunkId++);
}
}
}
}
}
if (target != null) {
target.save(generated);
return new FileInputStream(generated);
} else {
return null;
}
}
4.API与中文入门指南
有需要的可以留下邮箱。
官网地址:https://www.docx4java.org/trac/docx4j
github地址:https://github.com/plutext/docx4j
推荐学习:https://blog.csdn.net/sciurid