真正的美德不可没有实用的智慧,而实用的智慧也不可没有美德。——亚里士多德
可以使用Spire操作word
Spire.Doc for Java 是一款专业的 Java Word 组件,开发人员使用它可以轻松地将 Word 文档创建、读取、编辑、转换和打印等功能集成到自己的 Java 应用程序中。作为一款完全独立的组件,Spire.Doc for Java 的运行环境无需安装 Microsoft Office。
Spire.Doc for Java 能执行多种 Word 文档处理任务,包括生成、读取、转换和打印 Word 文档,插入图片,添加页眉和页脚,创建表格,添加表单域和邮件合并域,添加书签,添加文本和图片水印,设置背景颜色和背景图片,添加脚注和尾注,添加超链接,加密和解密 Word 文档,添加批注,添加形状等。
依赖
<dependency> <groupId>e-iceblue</groupId> <artifactId>spire.doc.free</artifactId> <version>3.9.0</version> </dependency>
再奉上一个自己写的工具类
package com.ruben.utils.coreUtils; import cn.hutool.core.date.DateUtil; import com.ruben.utils.FileUtils; import com.ruben.utils.StringKit; import com.ruben.utils.StringUtils; import com.ruben.utils.collection.MapUtil; import com.spire.doc.*; import com.spire.doc.collections.*; import com.spire.doc.documents.*; import com.spire.doc.fields.DocPicture; import com.spire.doc.fields.TextRange; import com.spire.doc.formatting.CharacterFormat; import com.spire.doc.formatting.ParagraphFormat; import lombok.extern.slf4j.Slf4j; import java.io.*; import java.net.URLEncoder; import java.text.DateFormat; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Pattern; /** * @ClassName: WordCoreUtils * @Date: 2020/12/8 0008 11:27 * @Description: 我还没有写描述 * @Author: <achao1441470436@gmail.com> */ @Slf4j public class WordCoreUtils { public static final String CHECKED = "■"; public static final String NO_CHECK = "□"; public static final String ENCLOSURE = "☼"; public static final String DATE_TIME_PATTERN_UTC = "yyyy-MM-dd'T'HH:mm:ss.sss'Z'"; private static final ThreadLocal<DateFormat> DATE_FORMAT_THREAD_LOCAL = ThreadLocal.withInitial(() -> new SimpleDateFormat(DATE_TIME_PATTERN_UTC)); /** * @MethodName: check * @Description: 打勾 * @Date: 2020/12/8 0008 11:35 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName] * @returnValue: void */ public static void check(Document doc, String bookmarkName) { check(doc, bookmarkName, "", true); } /** * @MethodName: check * @Description: 勾选 * @Date: 2020/12/14 0014 15:49 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName, text] * @returnValue: void */ public static void check(Document doc, String bookmarkName, String text, boolean checked) { if (checked) { // text = "\uF052" + text; text = CHECKED + text; } else { text = NO_CHECK + text; } // 定位书签 BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc); bookmarkNavigator.moveToBookmark(bookmarkName); // 创建段落 Paragraph para = new Paragraph(doc); // 创建文本内容 TextRange textRange = para.appendText(text); // 设置格式 CharacterFormat format = textRange.getCharacterFormat(); if (checked) { // 字体 // format.setFontName("Wingdings 2"); // 大小 format.setFontSize(15); } else { // 大小 format.setFontSize(9); } // 创建文本域 TextBodyPart bodyPart = new TextBodyPart(doc); // 添加段落到文本域 bodyPart.getBodyItems().add(para); // 替换书签内容 try { bookmarkNavigator.replaceBookmarkContent(bodyPart); } catch (Exception e) { log.error("书签《" + bookmarkName + "》丢失", e); } } /** * @MethodName: check * @Description: 批量勾选 * @Date: 2020/12/10 0010 10:17 * * * @author: <achao1441470436@gmail.com> * @param: [doc, set] * @returnValue: void */ public static void check(Document doc, Set<String> set) { set.forEach(s -> check(doc, s)); } /** * @MethodName: check * @Description: 填充书签 * @Date: 2020/12/9 0009 17:07 * * * @author: <achao1441470436@gmail.com> * @param: [condition, doc, bookmarkName] * @returnValue: void */ public static void check(boolean condition, Document doc, String bookmarkName) { if (!condition) { return; } check(doc, bookmarkName); } /** * @MethodName: fillText * @Description: 填充书签 * @Date: 2020/12/9 0009 13:03 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName, content] * @returnValue: void */ public static void fillText(Document doc, String bookmarkName, String content) { fillText(doc, bookmarkName, content, Boolean.TRUE); } /** * @MethodName: fillText * @Description: 填充书签 * @Date: 2020/12/9 0009 17:05 * * * @author: <achao1441470436@gmail.com> * @param: [condition, doc, bookmarkName, content] * @returnValue: void */ public static void fillText(boolean condition, Document doc, String bookmarkName, String content) { if (!condition) { return; } fillText(doc, bookmarkName, content); } public static final Pattern HTML_PATTERN = Pattern.compile("<.+?>"); /** * @MethodName: copyTable * @Description: 只复制表格 * @Date: 2020/12/8 0008 17:41 * * * @author: <achao1441470436@gmail.com> * @param: [table, start, rows] * @returnValue: void */ public static void copyTable(Table table, int start, int rows) { int end = start + rows; for (int j = start; j < end; j++) { TableRow row = table.getRows().get(j).deepClone(); table.getRows().insert(j + rows, row); } } /** * @MethodName: deepClone * @Description: 深克隆 * @Date: 2020/12/8 0008 19:20 * * * @author: <achao1441470436@gmail.com> * @param: [needCopy, tableRow] * @returnValue: void */ public static void deepClone(boolean needCopy, TableRow tableRow) { if (!needCopy) { return; } tableRow = tableRow.deepClone(); } /** * @MethodName: insertRow * @Description: 插入行 * @Date: 2020/12/8 0008 19:23 * * * @author: <achao1441470436@gmail.com> * @param: [table, start, rows, tableRow] * @returnValue: void */ public static void insertRow(boolean needCopy, Table table, int start, int rows, TableRow tableRow) { if (!needCopy) { return; } table.getRows().insert(start + rows, tableRow); } /** * @MethodName: fillTableCell * @Description: 赋值 * @Date: 2020/12/8 0008 19:41 * * * @author: <achao1441470436@gmail.com> * @param: [needCopy, tableCell, value] * @returnValue: void */ public static void fillTableCell(boolean needCopy, TableCell tableCell, String value) { if (!needCopy) { for (int i = 0; i < tableCell.getParagraphs().getCount(); i++) { tableCell.getParagraphs().removeAt(i); } } tableCell.addParagraph().appendText(value); } /** * @MethodName: appendCheck * @Description: 在段落里添加勾 * @Date: 2020/12/8 0008 20:35 * * * @author: <achao1441470436@gmail.com> * @param: [para] * @returnValue: void */ public static void appendCheck(boolean checked, Paragraph para) { if (checked) { TextRange textRange = para.appendText("\uF052"); CharacterFormat format = textRange.getCharacterFormat(); format.setFontName("Wingdings 2"); format.setFontSize(9); } else { para.appendText(NO_CHECK); } } /** * @MethodName: mergeTable * @Description: 合并表格 * @Date: 2020/12/9 0009 9:44 * * * @author: <achao1441470436@gmail.com> * @param: [documents] * @returnValue: com.spire.doc.Document */ public static Document mergeBigTable(Document... documents) { return mergeAddSectionTable(null, documents); } /** * @MethodName: fillOnlyText * @Description: 只填充文本不加下划线 * @Date: 2020/12/9 0009 15:38 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName, v] * @returnValue: void */ public static void fillOnlyText(Document doc, String bookmarkName, String v) { fillText(doc, bookmarkName, v, Boolean.FALSE); } /** * @MethodName: fillOnlyText * @Description: 只填充文本不加下划线 * @Date: 2020/12/9 0009 17:06 * * * @author: <achao1441470436@gmail.com> * @param: [condition, doc, bookmarkName, v] * @returnValue: void */ public static void fillOnlyText(boolean condition, Document doc, String bookmarkName, String v) { if (!condition) { return; } fillText(doc, bookmarkName, v, Boolean.FALSE); } /** * @MethodName: fillDate * @Description: 填充时间 * @Date: 2020/12/9 0009 16:56 * * * @author: <achao1441470436@gmail.com> * @param: [doc, date, yearBookmark, monthBookmark, dayBookmark] * @returnValue: void */ public static void fillDate(Document doc, Date date, String yearBookmark, String monthBookmark, String dayBookmark) { if (Objects.isNull(date)) { return; } Calendar calendar = Calendar.getInstance(); calendar.setTime(date); WordCoreUtils.fillOnlyText(doc, yearBookmark, String.valueOf(calendar.get(Calendar.YEAR))); WordCoreUtils.fillOnlyText(doc, monthBookmark, String.valueOf(calendar.get(Calendar.MONTH) + 1)); WordCoreUtils.fillOnlyText(doc, dayBookmark, String.valueOf(calendar.get(Calendar.DATE))); } /** * @MethodName: checkBox * @Description: 多选 * @Date: 2020/12/9 0009 17:01 * * * @author: <achao1441470436@gmail.com> * @param: [map<标签, 值>] * @returnValue: void */ public static void checkBox(Document doc, Map<String, String> map, String value) { map.forEach((k, v) -> check(value.contains(v), doc, k)); } /** * @MethodName: fillOnlyText * @Description: 批量赋值不加下划线 * @Date: 2020/12/9 0009 17:41 * * * @author: <achao1441470436@gmail.com> * @param: [doc, normalMap[map<标签, 值>]] * @returnValue: void */ public static void fillOnlyText(Document doc, Map<String, String> normalMap) { if (MapUtil.isEmpty(normalMap)) { return; } normalMap.forEach((k, v) -> fillOnlyText(StringKit.isNotBlank(v), doc, k, v)); } /** * @MethodName: fillText * @Description: 批量赋值加下划线 * @Date: 2020/12/9 0009 17:44 * * * @author: <achao1441470436@gmail.com> * @param: [doc, underLineMap] * @returnValue: void */ public static void fillText(Document doc, Map<String, String> underLineMap) { if (MapUtil.isEmpty(underLineMap)) { return; } underLineMap.forEach((k, v) -> fillText(StringKit.isNotBlank(v), doc, k, v)); } /** * @MethodName: mergeAutoFitTable * @Description: 设置列宽合并表格 * @Date: 2020/12/10 0010 16:56 * * * @author: <achao1441470436@gmail.com> * @param: [autoFit, documents] * @returnValue: com.spire.doc.Document */ public static Document mergeAutoFitTable(AutoFitBehaviorType autoFit, Document... documents) { // 创建结果文档 Document result = new Document(); // 结果文档添加section Section section = Optional.ofNullable(result.getLastSection()).orElse(result.addSection()); // 结果文档添加表格 TableCollection tableCollection = section.getTables(); // 表格数量 int count = tableCollection.getCount(); Table table = count > 0 ? tableCollection.get(count - 1) : section.addTable(true); // 遍历,添加 for (int i = 0; i < documents.length; i++) { // 获取文档中的sections SectionCollection sections = documents[i].getSections(); // 获取文档中的表格 TableCollection tables = sections.get(0).getTables(); // 获取表格中的列 RowCollection rows = tables.get(0).getRows(); for (int j = 0; j < rows.getCount(); j++) { // 遍历添加到需要添加的表格下方 table.getRows().add(rows.get(j).deepClone()); } if (Objects.nonNull(autoFit)) { // 列宽类型 table.autoFit(autoFit); } } return result; } /** * @MethodName: mergeSectionsTable * @Description: 合并表格 * @Date: 2020/12/10 0010 17:21 * * * @author: <achao1441470436@gmail.com> * @param: [documents] * @returnValue: com.spire.doc.Document */ public static Document mergeSectionsTable(AutoFitBehaviorType autoFit, Document... documents) { // 创建结果文档 Document result = new Document(); // 遍历,添加 for (Document document : documents) { // 结果文档添加section Section section = Optional.ofNullable(result.getLastSection()).orElse(result.addSection()); // 结果文档添加表格 Table table = section.getTables().getCount() == 0 ? section.addTable(true) : section.getTables().get(section.getTables().getCount() - 1); // 获取文档中的sections SectionCollection sections = document.getSections(); for (int k = 0; k < sections.getCount(); k++) { // 获取文档中的表格 TableCollection tables = sections.get(k).getTables(); Table currentTable = tables.get(0); // 获取表格中的列 RowCollection rows = currentTable.getRows(); for (int j = 0; j < rows.getCount(); j++) { TableRow row = rows.get(j).deepClone(); // 单行显示 onePageShow(row); // 遍历添加到需要添加的表格下方 table.getRows().add(row); } } if (Objects.nonNull(autoFit)) { //列宽自动适应窗口 table.autoFit(autoFit); } } return result; } private static void onePageShow(TableRow row) { CellCollection cells = row.getCells(); for (int i = 0; i < cells.getCount(); i++) { ParagraphCollection paragraphs = cells.get(i).getParagraphs(); for (int l = 0; l < paragraphs.getCount(); l++) { ParagraphFormat format = paragraphs.get(l).getFormat(); // 设置表格内容在同一页显示 format.setKeepFollow(true); } } } /** * @MethodName: mergeSectionsTable * @Description: 合并表格 * @Date: 2020/12/10 0010 17:56 * * * @author: <achao1441470436@gmail.com> * @param: [documents] * @returnValue: com.spire.doc.Document */ public static Document mergeSectionsTable(Document... documents) { // Auto_Fit_To_Window 列宽自适应窗口 return mergeSectionsTable(AutoFitBehaviorType.Auto_Fit_To_Window, documents); } /** * @MethodName: fillTexts * @Description: 多行替换书签 * @Date: 2020/12/11 0011 11:09 * * * @author: <achao1441470436@gmail.com> * @param: [doc, underlineMap] * @returnValue: void */ public static void fillTexts(Document doc, String bookmarkName, String value, int lines) { if (StringKit.isEmpty(value)) { return; } StringBuilder valueBuilder = new StringBuilder(" " + value); while (valueBuilder.length() < 47) { valueBuilder.append(" "); } while (valueBuilder.length() < 86 * lines) { valueBuilder.append("\n "); } value = valueBuilder.toString(); fillText(doc, bookmarkName, value); } /** * @MethodName: fillTextOneLine * @Description: 填充一行 * @Date: 2020/12/11 0011 11:58 * * * @author: <achao1441470436@gmail.com> * @param: [doc, underlineMap] * @returnValue: void */ public static void fillTextOneLine(Document doc, Map<String, String> underlineMap) { if (underlineMap.isEmpty()) { return; } underlineMap.forEach((bookmarkName, value) -> { StringBuilder valueBuilder = new StringBuilder(" " + value); while (valueBuilder.length() < 53) { valueBuilder.append(" "); } value = valueBuilder.toString(); fillText(doc, bookmarkName, value); }); } /** * @MethodName: concatWord * @Description: 连接word分页面 * @Date: 2020/12/11 0011 14:15 * * * @author: <achao1441470436@gmail.com> * @param: [documents] * @returnValue: com.spire.doc.Document */ public static Document concatWord(Document... documents) { Document result = new Document(); for (Document document : documents) { //获取第一个文档的最后一个section Section addSection = result.addSection(); //将第二个文档的段落作为新的段落添加到第一个文档的最后一个section for (Section section : (Iterable<Section>) document.getSections()) { for (DocumentObject obj : (Iterable<DocumentObject>) section.getBody().getChildObjects()) { addSection.getBody().getChildObjects().add(obj.deepClone()); } } } return result; } /** * @MethodName: picture * @Description: 填充图片 * @Date: 2021/1/5 0005 9:53 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName, filePath] * @returnValue: void */ public static void picture(Document doc, String bookmarkName, String filePath) { if (StringKit.isBlank(filePath)) { return; } try { // 对文件的中文【程序附件】编码 如果路径中有中文,需要用这个编码,不建议全部编码,会把符号弄掉 filePath = filePath.replace("程序附件", URLEncoder.encode("程序附件", "utf-8")); //定位到指定书签位置起始标签位置,插入图片 BookmarksNavigator bookmarksNavigator1 = new BookmarksNavigator(doc); bookmarksNavigator1.moveToBookmark(bookmarkName, true, false); Paragraph para = new Paragraph(doc); byte[] bytes = FileUtils.loadPicture(filePath); if (Objects.isNull(bytes)) { log.error("图片无法加载"); return; } DocPicture picture = para.appendPicture(bytes); picture.setWidth(100f); picture.setHeight(100f); picture.setDistanceLeft(50f); try { bookmarksNavigator1.insertParagraph(para); } catch (NullPointerException e) { log.error("书签《" + bookmarkName + "》丢失", e); } para.getFormat().setHorizontalAlignment(HorizontalAlignment.Center); } catch (Exception e) { log.error("错误", e); } } /** * @MethodName: setTableAutoFit * @Description: 设置表格列宽对齐方式 * @Date: 2020/12/16 0016 14:28 * * * @author: <achao1441470436@gmail.com> * @param: [autoFitBehaviorType, doc] * @returnValue: void */ public static void setTableAutoFit(AutoFitBehaviorType autoFitType, Document doc) { SectionCollection sections = doc.getSections(); for (int i = 0; i < sections.getCount(); i++) { TableCollection tables = sections.get(i).getTables(); for (int j = 0; j < tables.getCount(); j++) { tables.get(j).autoFit(autoFitType); } } } /** * @MethodName: setTableIsBreakAcrossPages * @Description: 设置表格是否跨页断行 * @Date: 2020/12/16 0016 14:39 * * * @author: <achao1441470436@gmail.com> * @param: [autoFitType, doc] * @returnValue: void */ public static void setTableIsBreakAcrossPages(boolean isBreakAcrossPages, Document doc) { SectionCollection sections = doc.getSections(); for (int i = 0; i < sections.getCount(); i++) { TableCollection tables = sections.get(i).getTables(); for (int j = 0; j < tables.getCount(); j++) { tables.get(j).getTableFormat().isBreakAcrossPages(isBreakAcrossPages); } } } /** * @MethodName: applyVerticalMerge * @Description: 合并单元格 * @Date: 2020/12/16 0016 14:52 * * * @author: <achao1441470436@gmail.com> * @param: [document, cells, startRows, endRows] * @returnValue: void */ public static void applyVerticalMerge(Document doc, int cells, int startRows, int endRows) { SectionCollection sections = doc.getSections(); for (int i = 0; i < sections.getCount(); i++) { TableCollection tables = sections.get(i).getTables(); for (int j = 0; j < tables.getCount(); j++) { tables.get(j).applyVerticalMerge(cells, startRows, endRows); } } } /** * @MethodName: fillEnclosure * @Description: 附件标志 * @Date: 2020/12/22 0022 15:34 * * * @author: <achao1441470436@gmail.com> * @param: [condition, doc, bookmarkName] * @returnValue: void */ public static void fillEnclosure(boolean condition, Document doc, String bookmarkName) { if (!condition) { return; } fillEnclosure(doc, bookmarkName); } /** * @MethodName: fillEnclosure * @Description: 附件标志 * @Date: 2020/12/31 0031 10:23 * * * @author: <achao1441470436@gmail.com> * @param: [file, doc, bookmarkName, enclosureMark] * @returnValue: void */ public static void fillEnclosure(String file, Document doc, String bookmarkName, String enclosureMark) { if (StringKit.isBlank(file)) { return; } // 定位书签 BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc); bookmarkNavigator.moveToBookmark(bookmarkName); // 创建段落 Paragraph para = new Paragraph(doc); // 创建文本内容 TextRange textRange = para.appendText(enclosureMark); // 设置格式 CharacterFormat format = textRange.getCharacterFormat(); // 字体 format.setFontName("Segoe UI Symbol"); // 大小 format.setFontSize(9); // 创建文本域 TextBodyPart bodyPart = new TextBodyPart(doc); // 添加段落到文本域 bodyPart.getBodyItems().add(para); // 替换书签内容 try { bookmarkNavigator.replaceBookmarkContent(bodyPart); } catch (Exception e) { log.error("书签《" + bookmarkName + "》丢失", e); } } /** * @MethodName: fillEnclosure * @Description: 附件标志 * @Date: 2020/12/22 0022 16:00 * * * @author: <achao1441470436@gmail.com> * @param: [file, doc, bookmarkName] * @returnValue: void */ public static void fillEnclosure(String file, Document doc, String bookmarkName) { if (StringKit.isEmpty(file)) { return; } fillEnclosure(doc, bookmarkName); } /** * @MethodName: fillEnclosure * @Description: 附件标志 * @Date: 2020/12/22 0022 15:45 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName] * @returnValue: void */ public static void fillEnclosure(Document doc, String bookmarkName) { fillEnclosure(WordCoreUtils.CHECKED, doc, bookmarkName, WordCoreUtils.ENCLOSURE); } /** * @MethodName: fillReplaceHtml * @Description: 填充替换掉html标签后的文本 * @Date: 2020/12/28 0028 15:02 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName, data] * @returnValue: void */ public static void fillReplaceHtml(Document doc, String bookmarkName, String data) { // 定位书签 BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc); bookmarkNavigator.moveToBookmark(bookmarkName); // 创建段落 Paragraph para = new Paragraph(doc); // 创建文本内容 TextRange textRange = para.appendText(StringUtils.replaceHtml(data)); // 设置格式 CharacterFormat format = textRange.getCharacterFormat(); // 大小 format.setFontSize(9); // 创建文本域 TextBodyPart bodyPart = new TextBodyPart(doc); // 添加段落到文本域 bodyPart.getBodyItems().add(para); // 替换书签内容 try { bookmarkNavigator.replaceBookmarkContent(bodyPart); } catch (Exception e) { log.error("书签《" + bookmarkName + "》丢失", e); } } /** * @MethodName: fillText * @Description: 填充书签 * @Date: 2020/12/9 0009 13:39 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName, content, underline] * @returnValue: void */ public static void fillText(Document doc, String bookmarkName, String content, boolean underline) { if (StringKit.isBlank(content)) { return; } // 定位书签 BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc); bookmarkNavigator.moveToBookmark(bookmarkName); // 创建段落 Paragraph para = new Paragraph(doc); // 创建文本内容 TextRange textRange = para.appendText(StringUtils.replaceHtml(content)); // 设置格式 CharacterFormat format = textRange.getCharacterFormat(); if (underline) { // 添加下划线 // format.setUnderlineStyle(UnderlineStyle.Single); } format.setFontSize(9); format.setFontName("宋体"); // 创建文本域 TextBodyPart bodyPart = new TextBodyPart(doc); // 添加段落到文本域 bodyPart.getBodyItems().add(para); // 替换书签内容 try { bookmarkNavigator.replaceBookmarkContent(bodyPart); } catch (NullPointerException e) { log.error("书签《" + bookmarkName + "》丢失", e); } } /** * @MethodName: fillHtml * @Description: 填充富文本 * @Date: 2020/12/28 0028 15:03 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName, htmlStr] * @returnValue: void */ public static void fillHtml(Document doc, String bookmarkName, String htmlStr) { if (StringKit.isBlank(htmlStr)) { return; } htmlStr = htmlStr.replaceAll("<[/]*p[ ]*>\\\\+[A-Za-z]", "</br>") .replaceAll("\t", "") .replaceAll("\n", "") .replaceAll(" ", " ") .replaceAll("<[/]*p[ ]*>", ""); if (!HTML_PATTERN.matcher(htmlStr).matches()) { fillOnlyText(doc, bookmarkName, htmlStr); return; } BookmarksNavigator bookmarksNavigator = new BookmarksNavigator(doc); bookmarksNavigator.moveToBookmark(bookmarkName, true, false); Paragraph para = doc.addSection().addParagraph(); para.appendHTML("<span style=\\\"font-family:'宋体'\\\">" + htmlStr + "</span>"); try { bookmarksNavigator.insertParagraph(para); } catch (NullPointerException e) { log.error("书签《" + bookmarkName + "》丢失", e); } } /** * @MethodName: fillLocalImage * @Description: 填充图片 * @Date: 2020/12/28 0028 15:03 * * * @author: <achao1441470436@gmail.com> * @param: [bytes, doc, bookmarkName] * @returnValue: void */ private static void fillLocalImage(byte[] bytes, Document doc, String bookmarkName, float width, float height) { if (Objects.isNull(bytes)) { return; } BookmarksNavigator bookmarksNavigator = new BookmarksNavigator(doc); bookmarksNavigator.moveToBookmark(bookmarkName, true, false); Paragraph para = new Paragraph(doc); DocPicture picture = para.appendPicture(bytes); if (picture.getHeightScale() > width) { picture.setWidth(width); } if (picture.getHeightScale() > height) { picture.setHeight(height); } // picture.setDistanceLeft(50f); try { bookmarksNavigator.insertParagraph(para); } catch (NullPointerException e) { log.error("书签《" + bookmarkName + "》丢失", e); } } /** * @MethodName: loadLocalImgToByteArray * @Description: 加载本地图片 * @Date: 2020/12/28 0028 15:03 * * * @author: <achao1441470436@gmail.com> * @param: [picturePath] * @returnValue: byte[] */ private static byte[] loadLocalImgToByteArray(String picturePath) { InputStream dataInputStream = null; ByteArrayOutputStream output = null; byte[] result = new byte[0]; try { dataInputStream = new FileInputStream(picturePath); output = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = dataInputStream.read(buffer)) > 0) { output.write(buffer, 0, length); } result = output.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { try { //这种写法,保证了即使遇到异常情况,也会关闭流对象。 if (dataInputStream != null) { dataInputStream.close(); } if (output != null) { output.close(); } } catch (IOException e) { e.printStackTrace(); } } File file = new File(picturePath); if (file.exists()) { file.delete(); } return result; } /** * @MethodName: fillDateStr * @Description: 填充日期字符串 * @Date: 2021/1/5 0005 16:39 * * * @author: <achao1441470436@gmail.com> * @param: [doc, bookmarkName, time] * @returnValue: void */ public static void fillDateStr(Document doc, String bookmarkName, String time) { if (StringKit.isEmpty(time)) { return; } String chineseDate; try { chineseDate = DateUtil.formatChineseDate(DateUtil.parse(time).toJdkDate(), false); } catch (Exception e) { chineseDate = DateUtil.formatChineseDate(DATE_FORMAT_THREAD_LOCAL.get().parse(time, new ParsePosition(0)), false); } fillOnlyText(doc, bookmarkName, chineseDate); } /** * @MethodName: mergeAddSectionTable * @Description: 直接添加section方式合并 * @Date: 2021/1/6 0006 13:54 * * * @author: <achao1441470436@gmail.com> * @param: [autoFit, documents] * @returnValue: com.spire.doc.Document */ public static Document mergeAddSectionTable(AutoFitBehaviorType autoFit, Document... documents) { // 创建结果文档 Document result = new Document(); // 遍历,添加 for (int i = 0; i < documents.length; i++) { // 结果文档添加section Section section = Optional.ofNullable(result.getLastSection()).orElse(result.addSection()); // 设置不换页 section.setBreakCode(SectionBreakType.No_Break); // 结果文档添加表格 Table table = section.addTable(true); // 获取文档中的sections SectionCollection sections = documents[i].getSections(); // 获取第一个section,没有就新增一个 Section section1 = sections.getCount() == 0 ? documents[i].addSection() : sections.get(0); // 获取文档中的所有表格 TableCollection tables = section1.getTables(); // 获取第一个表格中的列,没有表格就新增一个 RowCollection rows = (tables.getCount() == 0 ? section1.addTable() : tables.get(0)).getRows(); for (int j = 0; j < rows.getCount(); j++) { TableRow row = rows.get(j).deepClone(); // 内容显示到一页 onePageShow(row); // 遍历添加到需要添加的表格下方 table.getRows().add(row); } if (Objects.nonNull(autoFit)) { // 列宽 table.autoFit(autoFit); } } return result; } /** * @MethodName: printTable * @Description: 打印表结构进行分析 * @Date: 2021/1/7 0007 14:55 * * * @author: <achao1441470436@gmail.com> * @param: [document] * @returnValue: void */ public static void printTable(Document document) { SectionCollection sections = document.getSections(); for (int i = 0; i < sections.getCount(); i++) { System.out.print("section:" + i + " "); TableCollection tables = sections.get(i).getTables(); for (int j = 0; j < tables.getCount(); j++) { System.out.print("table:" + j + " "); RowCollection rows = tables.get(j).getRows(); for (int k = 0; k < rows.getCount(); k++) { System.out.print("row:" + k + " "); CellCollection cells = rows.get(k).getCells(); for (int l = 0; l < cells.getCount(); l++) { System.out.print("cell:" + l + " "); TableCell tableCell = cells.get(l); ParagraphCollection paras = tableCell.getParagraphs(); for (int m = 0; m < paras.getCount(); m++) { System.out.print("para:" + m + " "); System.out.print(paras.get(m).getText() + " "); } System.out.print("\t"); } System.out.println(); } } } } /** * @MethodName: fillHalfDownText * @Description: 加一行空行填充 * @Date: 2021/1/7 0007 15:07 * * * @author: <achao1441470436@gmail.com> * @param: [needDown, checked, doc, bookmarkName, text] * @returnValue: void */ public static void fillHalfDownText(boolean needDown, Document doc, String bookmarkName, String content) { if (StringKit.isBlank(content)) { return; } // 定位书签 BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc); bookmarkNavigator.moveToBookmark(bookmarkName); // 创建段落 Paragraph para = new Paragraph(doc); // 创建文本内容 TextRange textRange = para.appendText(needDown ? ("\n" + content) : StringUtils.replaceHtml(content)); // 设置格式 CharacterFormat format = textRange.getCharacterFormat(); format.setFontName("Segoe UI Symbol"); format.setFontSize(9); // 创建文本域 TextBodyPart bodyPart = new TextBodyPart(doc); // 添加段落到文本域 bodyPart.getBodyItems().add(para); // 替换书签内容 try { bookmarkNavigator.replaceBookmarkContent(bodyPart); } catch (NullPointerException e) { log.error("书签《" + bookmarkName + "》丢失", e); } } /** * @MethodName: onePageShow * @Description: 设置表格内容在同一页显示 * @Date: 2021/1/8 0008 10:08 * * * @author: <achao1441470436@gmail.com> * @param: [doc] * @returnValue: void */ public static void onePageShow(Document document) { SectionCollection sections = document.getSections(); for (int i = 0; i < sections.getCount(); i++) { TableCollection tables = sections.get(i).getTables(); for (int j = 0; j < tables.getCount(); j++) { Table table = tables.get(j); table.getTableFormat().isBreakAcrossPages(true); RowCollection rows = table.getRows(); for (int k = 0; k < rows.getCount(); k++) { TableRow row = rows.get(k); onePageShow(row); } } } } /** * @MethodName: everyPageSNNumber * @Description: 每页加sn * @Date: 2021/1/8 0008 11:16 * * * @author: <achao1441470436@gmail.com> * @param: [doc, snNumber] * @returnValue: void */ public static void everyPageSNNumber(Document doc, String snNumber) { // 获取页首 HeaderFooter header = doc.getSections().get(0).getHeadersFooters().getHeader(); Paragraph paragraph = header.addParagraph(); paragraph.appendText(" SN:" + Optional.ofNullable(snNumber).orElseGet(String::new)); //将段落居中 paragraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Left); } }