1.情景展示
用java编辑word文档
2.准备工作
通过docx4j实现
所需jar包
<!-- https://mvnrepository.com/artifact/org.docx4j/docx4j-JAXB-Internal --> <dependency> <groupId>org.docx4j</groupId> <artifactId>docx4j-JAXB-Internal</artifactId> <version>8.2.9</version> </dependency>
3.功能实现
生成word文件
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
/* * 创建docx文档 * @attention: * 1.原文件如果已经存在的情况下,原文件中的内容会被清空 * 2.在windows中无论后缀名的大小写问题,只要是相同后缀名且前缀也相同就是同一文件, * 当是同一后缀名且大小写不一致时,已存在的文件后缀名大小写不会改动 * 3.如果原文件已存在,则该word文件不能处于打开状态(没有处在使用中) * @date: 2021-05-12 14:57 * @param: fileSavePath * 文件保存所在路径 * @param: fileSaveName * @return: boolean * Word创建成功、失败 */ private static boolean createDocx(String fileSavePath, String fileSaveName) { try { // 确保文件的后缀名为".docx" if (!fileSaveName.substring(fileSaveName.indexOf(".")).equalsIgnoreCase(".docx")) fileSaveName += ".docx"; // 确保文件的绝对路径 if (fileSavePath.endsWith("/") || fileSavePath.endsWith("\\")) fileSavePath += fileSaveName; else fileSavePath += File.separator + fileSaveName; // Create the package 建包 WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage(); // 另存为新的文件 保存 // 如果原文件已存在的话,里面的内容会被清空 wordMLPackage.save(new File(fileSavePath)); log.info("docx创建成功"); return true; } catch (Exception e) { e.printStackTrace(); log.error("docx创建失败:", e.getMessage()); return false; } }
追加内容
import org.docx4j.openpackaging.exceptions.Docx4JException; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; import org.jetbrains.annotations.NotNull; import java.io.*; import java.util.List;
/* * 增加段落内容 * @attention: * 1.原文件不能在的话,会报错 * 2.原文件不能处于打开状态(没有处在使用中) * @date: 2021-05-12 15:28 * @param: docxAbsolutePath * 文件的绝对(完整)路径,比如:C:\Users\Marydon\Desktop\aaaaa.docx * @param: textList * 要添加的段落集合 * @return: void */ public static void insertParagraphs(String docxAbsolutePath, @NotNull List<String> textList) { try { // 加载word文件 WordprocessingMLPackage wPackage = WordprocessingMLPackage.load(new File(docxAbsolutePath)); MainDocumentPart mdt = wPackage.getMainDocumentPart(); // 添加段落内容(原文件内容会被覆盖掉) textList.forEach(simpleText -> { mdt.addParagraphOfText(simpleText); // mdt.addStyledParagraphOfText()可以指定段落的级别,如:标题使用Title,副标题使用Subtitle等 }); // 如果仅仅是想要实现换行的话,除了增加段落外,还可以使用换行符来实现 // mdt.addParagraphOfText("张三\r\n李四"); // 保存 wPackage.save(new File(docxAbsolutePath)); log.info("段落批量添加成功"); } catch (Docx4JException e) { e.printStackTrace(); log.error("段落添加失败:", e.getMessage()); } }
插入图片
import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.docx4j.dml.wordprocessingDrawing.Inline; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; import org.docx4j.wml.Drawing; import org.docx4j.wml.ObjectFactory; import org.docx4j.wml.P; import org.docx4j.wml.R; import org.jetbrains.annotations.NotNull; import java.io.File;
/* * 插入图片 * @attention: * 1.需要确保文件的有效性(真实存在、路径完整) * 2.原文件不能处于打开状态(没有处在使用中) * @date: 2021-05-12 17:45 * @param: docxCompleteRoute * word文档的绝对(完整)路径 * @param: imgCompleteRoute * 图片的绝对(完整)路径 * @return: boolean * 插入成功、失败 */ public static boolean insertImg(String docxCompleteRoute, String imgCompleteRoute) { try { // 图片转byte[] byte[] bytes = FileUtils.readFileToByteArray(new File(imgCompleteRoute)); // 加载word文档 // 创建了一个包(package)来容纳文档 WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(docxCompleteRoute)); // 插入图片(将图片添加到包中) addImageToPackage(wordMLPackage, bytes); // 保存这个包 wordMLPackage.save(new File(docxCompleteRoute)); log.info("图片插入成功"); return true; } catch (Exception e) { e.printStackTrace(); log.error("图片插入失败:" + e.getMessage()); return false; } } /** * 将图片放到文档的包中 * * Docx4j拥有一个由字节数组创建图片部件的工具方法, 随后将其添加到给定的包中. 为了能将图片添加 到一个段落中, * 我们需要将图片转换成内联对象. 这也有一个方法, 方法需要文件名提示, 替换文本, 两个id标识符和一个是嵌入还是链接到的指示作为参数. * 一个id用于文档中绘图对象不可见的属性, 另一个id用于图片本身不可见的绘制属性. 最后我们将内联 对象添加到段落中并将段落添加到包的主文档部件. * * @param wordMLPackage * 要添加图片的包 * @param bytes * 图片对应的字节数组 * @throws Exception * 不幸的createImageInline方法抛出一个异常(没有更多具体的异常类型) */ private static void addImageToPackage(WordprocessingMLPackage wordMLPackage, byte[] bytes) throws Exception { // 创建图片部件 BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); // 创建内联对象 Inline inline = imagePart.createImageInline("Filename hint","Alternative text", 1, 2, false); // 将内联对象添加到段落中 // 实现方法在下方 P paragraph = addInlineImageToParagraph(inline); // 将段落添加到文档中 wordMLPackage.getMainDocumentPart().addObject(paragraph); } /** * 将内联对象添加到段落中 * * 创建一个对象工厂并用它创建一个段落和一个可运行块R. 然后将可运行块添加到段落中. 接下来创建一个图画并将其添加到可运行块R中. 最后我们将内联 * 对象添加到图画中并返回段落对象. * * @param inline * 包含图片的内联对象. * @return 包含图片的段落 */ @NotNull private static P addInlineImageToParagraph(Inline inline) { // 采用工厂类增加段落的方法 ObjectFactory factory = new ObjectFactory(); // 创建段落 P paragraph = factory.createP(); // R是一个运行块,负责便于将多个属性相同的Object对象统一操作,通过其内部的content成员变量可以添加内容 R run = factory.createR(); paragraph.getContent().add(run); Drawing drawing = factory.createDrawing(); run.getContent().add(drawing); drawing.getAnchorOrInline().add(inline); return paragraph; }
写在最后
哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!
相关推荐: