使用Docx4j向指定位置插入图片
pom.xml
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>3.3.1</version>
</dependency>
代码部分:
import lombok.extern.slf4j.Slf4j;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.jaxb.Context;
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 java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
/**
* @Author: XueWeiDong
* @Description:
* @Date: 14:30 2019/12/14
*/
@Slf4j
public class DocxIO {
//表示一个\t
private static final String space = " ";
public static void main(String[] args) throws Exception{
String imagePath = "****.jpg";
File file = new File("****.docx");
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(file);
ObjectFactory factory= Context.getWmlObjectFactory();
//得到主段落
MainDocumentPart documentPart = mlPackage.getMainDocumentPart();
//提取正文
Document document = documentPart.getContents();
//提取所有段落
List<Object> paragraphs = document.getBody().getContent();
//拿到指定段落
P paragraph = new P();
for (Object object:paragraphs){
if (object.toString().contains("正文正文:")){
paragraph = (P)object;
// getParagraphPPr(paragraph);
break;
}
}
//要添加的内容
R run = getRun(factory, imagePath, mlPackage);
//删除原来段落的内容
removeAll(paragraph);
//设置段落格式
setParagraphStyle(paragraph);
paragraph.getContent().add(run);
mlPackage.save(file);
}
//创建要添加的内容
public static R getRun(ObjectFactory factory, String imgPath, WordprocessingMLPackage mlPackage) throws Exception{
Text text = factory.createText();
text.setValue("重新编辑的内容:");
// R对象是匿名的复杂类型
R run = getR(factory);
// drawing理解为画布?
Drawing drawing = getDraw(imgPath, mlPackage, factory);
//将文字和图片按照顺序放入R中
run.getContent().add(setSpace(text));
run.getContent().add(text);
run.getContent().add(drawing);
run.getContent().add(setSpace());
run.getContent().add(setSpace(text));
return run;
}
//创建图片
public static Drawing getDraw(String imgPath, WordprocessingMLPackage mlPackage, ObjectFactory factory) throws Exception{
InputStream is = new FileInputStream(imgPath);
byte[] bytes = IOUtils.toByteArray(is);
// 创建一个行内图片
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(mlPackage, bytes);
//设置图片最大宽度
Inline inline = imagePart.createImageInline(null, null, 0, 1, false, 1500);
// drawing理解为画布
Drawing drawing = factory.createDrawing();
drawing.getAnchorOrInline().add(inline);
return drawing;
}
//设置文字间距为四个\t
public static Text setSpace(Text text){
Text result = new Text();
result.setValue(text.getValue()+space+space+space+space);
result.setSpace("preserve");
return result;
}
//获取空格
public static Text setSpace(){
Text result = new Text();
result.setValue(space+space+space+space);
result.setSpace("preserve");
return result;
}
//创建R对象
public static R getR(ObjectFactory factory){
return factory.createR();
}
//删除段落全部内容
public static void removeAll(P p){
p.getContent().removeAll(p.getContent());
}
//获取段落的部分格式(不完整)
public static void getParagraphPPr(P p){
PPr pPr = p.getPPr();
log.info("行间距:{}", pPr.getSpacing().getLine());
log.info("字体大小:{}", pPr.getRPr().getSz().getVal());
}
public static void setParagraphStyle(P p){
PPrBase.Spacing spacing = new PPrBase.Spacing();
spacing.setLineRule(STLineSpacingRule.AUTO);
p.getPPr().setSpacing(spacing);
}
}
注意的要点:
- 插入内容可以通过书签拿到指定位置,或者自己循环遍历段落到指定位置。
- 插入内容只能插入到指定位置所在段落的最后, 如果想要插入到段落中, 可以将该段落内容清空再按自己的方式编辑。
- 插入图片显示不完整, 记得设置行距规则为AUTO, 代码中的最后一个方法。