java生成docx文件、pdf文件、docx转pdf、docx转图片 pdf转图片工具
docx4j生成docx文件、pdf文件、docx轉(zhuǎn)pdf、docx轉(zhuǎn)圖片 pdf轉(zhuǎn)圖片工具
最近寫項(xiàng)目時(shí)遇到一些操作數(shù)據(jù)填充word、pdf以及word轉(zhuǎn)pdf、word轉(zhuǎn)圖片的需求。網(wǎng)絡(luò)搜索資料經(jīng)整理如下
操作office文檔、pdf一般來說有好幾種實(shí)現(xiàn)方式
1、docx4j+apache.pdfbox
1.1 引入maven
<!-- pdf 轉(zhuǎn)圖片 --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.25</version></dependency><!--<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.10.1</version></dependency>--><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/org.apache.poi.xwpf.converter.pdf--><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>org.apache.poi.xwpf.converter.pdf</artifactId><version>1.0.4</version></dependency><!-- pdf 轉(zhuǎn)圖片 --><!-- docx4j 創(chuàng)建docx文件、pdf文檔、word轉(zhuǎn)pdf文檔--><dependency><groupId>org.docx4j</groupId><artifactId>docx4j-JAXB-Internal</artifactId><version>8.2.4</version></dependency><dependency><groupId>org.docx4j</groupId><artifactId>docx4j-export-fo</artifactId><version>8.2.4</version></dependency><!-- docx4j 創(chuàng)建docx文件、pdf文檔、word轉(zhuǎn)pdf文檔-->1.2 工具類
package com.sl.utils.office.word;import com.sl.utils.id.IDUtils; import org.apache.commons.collections4.MapUtils; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; import org.docx4j.Docx4J; import org.docx4j.TraversalUtil; import org.docx4j.XmlUtils; import org.docx4j.dml.wordprocessingDrawing.Inline; import org.docx4j.finders.RangeFinder; import org.docx4j.fonts.IdentityPlusMapper; import org.docx4j.fonts.Mapper; import org.docx4j.fonts.PhysicalFonts; import org.docx4j.jaxb.Context; import org.docx4j.openpackaging.exceptions.Docx4JException; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; import org.docx4j.wml.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory;import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; /*** docx4j生成docx文件、pdf文件、docx轉(zhuǎn)pdf、docx轉(zhuǎn)圖片 pdf轉(zhuǎn)圖片工具** 有三種方式* 1 通過占位符** <p>* 通過docx文件的書簽、占位符替換變量* <p>* 通過占位符替換注意* * 通過占位符替換注意 -----------坑坑坑坑 直接再docx文件中進(jìn)行修改占位符不一定會(huì)連續(xù)!!!-----------* ${var}必須是連續(xù)的,否則取不到變量。有時(shí)候取不到變量的時(shí)候可以抓換為xml然后查看你的變量是否是連續(xù)的* 可以通過如下方式解決 現(xiàn)在docx文件中寫入占位符然后* 把當(dāng)前docx文件用rar或zip打開,找到其中的 word/document.xml文件,修改占位符連續(xù)* <p>* 比如把* <w:r>* <w:t>${na</w:t>* </w:r>* <w:r>* <w:t>me}</w:t>* </w:r>* 修改為* <w:r>* <w:t>${name}</w:t>* </w:r>* 2、全部通過書簽* 3、通過域變量* 通過域變量需要重寫 docx4居中 XmlUtils 工具類中unmarshallFromTemplate方法 以適配域變量* 具體目錄在 org.docx4j* @author gaoxueyong* @create at: 2021/12/28 下午15:02*/ public class DocxAndPdfAndImgUtils {private static final Logger log = LoggerFactory.getLogger(DocxAndPdfAndImgUtils.class);private static WordprocessingMLPackage wordMLPackage;private static ObjectFactory factory;/*** 通過docx模板獲取docx模板轉(zhuǎn)換的圖片* @param templatePath 模板文件* @param mappings 要匹配的占位符數(shù)據(jù)* @param fileMapping 書簽名稱對(duì)于的文件* @return*/public static List<byte[]> getPngByDocxTemplate(String templatePath, Map<String, String> mappings, Map<String, byte[]> fileMapping) {return pdfToImg(getPdfFile(templatePath, mappings, fileMapping));}/*** 通過模板獲取轉(zhuǎn)換后docx的二進(jìn)制數(shù)組* @param templatePath 模板文件* @param mappings 要匹配的占位符數(shù)據(jù)* @param fileMapping 書簽名稱對(duì)于的文件* @return*/public static byte[] getDocxByTemplate(String templatePath, Map<String, String> mappings, Map<String, byte[]> fileMapping) {File docxFile = getDocxFile(templatePath, mappings, fileMapping);try {if (null == docxFile) {return null;}byte[] bytes = Files.readAllBytes(docxFile.toPath());if (docxFile.exists()) {docxFile.delete();}return bytes;} catch (IOException e) {log.error("獲取文件失敗");if (docxFile.exists()) {docxFile.delete();}return null;}}/*** 通過模板獲取轉(zhuǎn)換后pdf文件* @param templatePath 模板文件* @param mappings 要匹配的占位符數(shù)據(jù)* @param fileMapping 書簽名稱對(duì)于的文件* @return*/public static byte[] getPdfFile(String templatePath, Map<String, String> mappings, Map<String, byte[]> fileMapping){try {File docxFile = getDocxFile(templatePath, mappings, fileMapping);if(null == docxFile){return null;}WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(docxFile);Path pdf = Files.createTempFile(IDUtils.getPrimaryId(), "pdf");File pdfFile = pdf.toFile();if(null == pdfFile){log.error("創(chuàng)建文件失敗");return null;}Docx4J.toPDF(wordMLPackage, new FileOutputStream(pdfFile));if(docxFile.exists()){docxFile.delete();}byte[] bytes = Files.readAllBytes(pdf);if(pdfFile.exists()){pdfFile.delete();}return bytes;} catch (Docx4JException e) {log.error("bookReplaceVarText error:Docx4JException ", e);return null;} catch (Exception e) {log.error("bookReplaceVarText error:Docx4JException ", e);return null;}}/*** 通過文件輸入流獲取pdf文檔的二進(jìn)制數(shù)組* @param docxInputstream* @return*/public static byte[] getPdfByte(InputStream docxInputstream){try {if(null == docxInputstream){return null;}WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(docxInputstream);Path pdf = Files.createTempFile(IDUtils.getPrimaryId(), "pdf");File pdfFile = pdf.toFile();if(null == pdfFile){log.error("創(chuàng)建文件失敗");return null;}Docx4J.toPDF(wordMLPackage, new FileOutputStream(pdfFile));byte[] bytes = Files.readAllBytes(pdf);if(pdfFile.exists()){pdfFile.delete();}return bytes;} catch (Docx4JException e) {log.error("bookReplaceVarText error:Docx4JException ", e);return null;} catch (Exception e) {log.error("bookReplaceVarText error:Docx4JException ", e);return null;}}/*** 通過模板獲取轉(zhuǎn)換后docx文件* @param templatePath 模板文件* @param mappings 要匹配的占位符數(shù)據(jù)* @param fileMapping 書簽名稱對(duì)于的文件* @return*/public static File getDocxFile(String templatePath, Map<String, String> mappings, Map<String, byte[]> fileMapping){try {wordMLPackage = WordprocessingMLPackage.load(new File(templatePath));MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();if(MapUtils.isNotEmpty(mappings)){mainDocumentPart.variableReplace(mappings);}factory = Context.getWmlObjectFactory();Document wmlDoc = (Document) mainDocumentPart.getJaxbElement();Body body = wmlDoc.getBody();// 提取正文中所有段落List<Object> paragraphs = body.getContent();// 提取書簽并創(chuàng)建書簽的游標(biāo)RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");new TraversalUtil(paragraphs, rt);// 遍歷書簽for (CTBookmark bm : rt.getStarts()) {log.info("標(biāo)簽名稱:" + bm.getName());if(MapUtils.isEmpty(fileMapping)){break;}if (fileMapping.containsKey(bm.getName())) {addImage(wordMLPackage, bm, fileMapping.get(bm.getName()));}else {if(mappings.containsKey(bm.getName())){replaceText (bm, mappings.get(bm.getName()));}}}wordMLPackage.setFontMapper(getFontMap());Path docx = Files.createTempFile(IDUtils.getPrimaryId(), "docx");File docxFile = docx.toFile();Docx4J.save(wordMLPackage, docxFile);return docxFile;} catch (Docx4JException e) {log.error("bookReplaceVarText error:Docx4JException ", e);return null;} catch (Exception e) {log.error("bookReplaceVarText error:Docx4JException ", e);return null;}}/*** 在標(biāo)簽處插入內(nèi)容* @param bm* @param object* @throws Exception*/public static void replaceText(CTBookmark bm, Object object) throws Exception {if (object == null) {return;}// do we have data for this one?if (bm.getName() == null){return;}String value = object.toString();try {// Can't just remove the object from the parent,// since in the parent, it may be wrapped in a JAXBElementList<Object> theList = null;ParaRPr rpr = null;if (bm.getParent() instanceof P) {PPr pprTemp = ((P) (bm.getParent())).getPPr();if (pprTemp == null) {rpr = null;} else {rpr = ((P) (bm.getParent())).getPPr().getRPr();}theList = ((ContentAccessor) (bm.getParent())).getContent();} else {return;}int rangeStart = -1;int rangeEnd = -1;int i = 0;for (Object ox : theList) {Object listEntry = XmlUtils.unwrap(ox);if (listEntry.equals(bm)) {if (((CTBookmark) listEntry).getName() != null) {rangeStart = i + 1;}} else if (listEntry instanceof CTMarkupRange) {if (((CTMarkupRange) listEntry).getId().equals(bm.getId())) {rangeEnd = i - 1;break;}}i++;}int x = i - 1;// if (rangeStart > 0 && x >= rangeStart) {// Delete the bookmark rangefor (int j = x; j >= rangeStart; j--) {theList.remove(j);}// now add a runR run = factory.createR();Text t = factory.createText();// if (rpr != null)// run.setRPr(paraRPr2RPr(rpr));t.setValue(value);run.getContent().add(t);// t.setValue(value);theList.add(rangeStart, run);// }} catch (ClassCastException cce) {log.error("error", cce);}}/*** 插入圖片* @param wPackage* @param bm* @param bytes*/public static void addImage(WordprocessingMLPackage wPackage, CTBookmark bm,byte[] bytes) { // log.info("addImage :->{},{},{}", wPackage, bm);if(null == bytes){return;}try {// 這兒可以對(duì)單個(gè)書簽進(jìn)行操作,也可以用一個(gè)map對(duì)所有的書簽進(jìn)行處理// 獲取該書簽的父級(jí)段落P p = (P) (bm.getParent());// R對(duì)象是匿名的復(fù)雜類型,然而我并不知道具體啥意思,估計(jì)這個(gè)要好好去看看ooxml才知道R run = factory.createR();// 讀入圖片并轉(zhuǎn)化為字節(jié)數(shù)組,因?yàn)閐ocx4j只能字節(jié)數(shù)組的方式插入圖片 // byte[] bytes = IOUtils.toByteArray(new FileInputStream(file));// InputStream is = new FileInputStream;// byte[] bytes = IOUtils.toByteArray(inputStream);// byte[] bytes = FileUtil.getByteFormBase64DataByImage("");// 開始創(chuàng)建一個(gè)行內(nèi)圖片BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wPackage, bytes);// 最后一個(gè)參數(shù)是限制圖片的寬度,縮放的依據(jù)Inline inline = imagePart.createImageInline(null, null, 0, 1, false, 2350);// 獲取該書簽的父級(jí)段落// drawing理解為畫布?Drawing drawing = factory.createDrawing();drawing.getAnchorOrInline().add(inline);run.getContent().add(drawing);p.getContent().add(run);} catch (Exception e) {log.error("", e);}}/*** 解決轉(zhuǎn)換后數(shù)據(jù)顯示異常的問題* @return*/private static Mapper getFontMap(){Mapper fontMapper = new IdentityPlusMapper();fontMapper.put("隸書", PhysicalFonts.get("LiSu"));fontMapper.put("宋體", PhysicalFonts.get("SimSun"));fontMapper.put("微軟雅黑", PhysicalFonts.get("Microsoft Yahei"));fontMapper.put("黑體", PhysicalFonts.get("SimHei"));fontMapper.put("楷體", PhysicalFonts.get("KaiTi"));fontMapper.put("新宋體", PhysicalFonts.get("NSimSun"));fontMapper.put("華文行楷", PhysicalFonts.get("STXingkai"));fontMapper.put("華文仿宋", PhysicalFonts.get("STFangsong"));fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));fontMapper.put("幼圓", PhysicalFonts.get("YouYuan"));fontMapper.put("華文宋體", PhysicalFonts.get("STSong"));fontMapper.put("華文中宋", PhysicalFonts.get("STZhongsong"));fontMapper.put("等線", PhysicalFonts.get("SimSun"));fontMapper.put("等線 Light", PhysicalFonts.get("SimSun"));fontMapper.put("華文琥珀", PhysicalFonts.get("STHupo"));fontMapper.put("華文隸書", PhysicalFonts.get("STLiti"));fontMapper.put("華文新魏", PhysicalFonts.get("STXinwei"));fontMapper.put("華文彩云", PhysicalFonts.get("STCaiyun"));fontMapper.put("方正姚體", PhysicalFonts.get("FZYaoti"));fontMapper.put("方正舒體", PhysicalFonts.get("FZShuTi"));fontMapper.put("華文細(xì)黑", PhysicalFonts.get("STXihei"));fontMapper.put("宋體擴(kuò)展", PhysicalFonts.get("simsun-extB"));fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));fontMapper.put("新細(xì)明體", PhysicalFonts.get("SimSun"));return fontMapper;}/*** pdf 轉(zhuǎn)圖片* @param pdfFile* @return*/public static List<byte[]> pdfToImg(byte[] pdfFile) {PDDocument doc = null;List<byte[]> outFile = new ArrayList<>();try {doc = PDDocument.load(pdfFile);PDFRenderer render = new PDFRenderer(doc);int count = doc.getNumberOfPages();for (int i = 0; i < count; i++) {// 設(shè)置圖片的分辨率BufferedImage image = render.renderImageWithDPI(i, 296);// 如果是PNG圖片想要背景透明的話使用下面這個(gè)// BufferedImage image = render.renderImageWithDPI(i, 296,// ImageType.ARGB);Path png = Files.createTempFile(IDUtils.getPrimaryId() + "_" + i, "png");File pngFile = png.toFile();ImageIO.write(image, "PNG", pngFile);outFile.add(Files.readAllBytes(png));pngFile.delete();}} catch (IOException e) {log.error("pdf轉(zhuǎn)換圖片失敗!");} finally {if (doc != null) {try {doc.close();} catch (IOException e) {log.error("關(guān)閉PDDocument失敗");}}return outFile;}} }1.2.1 重寫 XmlUtils以適配域變量
重寫 XmlUtils 工具類中unmarshallFromTemplate方法 以適配域變量
1.3 關(guān)于模板
1.3.1 新建一個(gè)docx文檔如并添加占位符 (不推薦 可以全部都是用標(biāo)簽或域變量)
頭像出需要添加書簽,書簽用以替換圖片
1.3.2 修改占位符使其連續(xù)
用zip或rar工具打開docx文檔并找到word/document.xml文件進(jìn)行編輯
偷偷的告訴你,其實(shí)docx文檔也是壓縮包,可以修改其后綴直接變成zip文件
打開document.xml文檔如下發(fā)現(xiàn)剛才的占位符是不連續(xù)的,我們要修改使其連續(xù)
使用編輯器修改后如下,然后把該文件寫會(huì)到word問里,或者通過zip工具放進(jìn)去
現(xiàn)在就可以直接調(diào)用工具方法替換數(shù)據(jù)以及圖片了
1.3.2 使用域變量+書簽(圖片需要使用書簽)
注意 使用域變量需要重寫 docx4居中 XmlUtils 工具類中unmarshallFromTemplate方法 以適配域變量
2、xdocreport
2.1 引入maven
<!-- xdocreport 生成word、pdf --><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.xdocreport.document.docx --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.document.docx</artifactId><version>2.0.2</version></dependency><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.xdocreport.template.freemarker --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId><version>2.0.2</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.converter.docx.xwpf</artifactId><version>2.0.2</version></dependency><!-- xdocreport 生成word、pdf --><!-- pdf轉(zhuǎn)圖片 --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.25</version></dependency><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.poi.xwpf.converter.pdf --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId><version>2.0.2</version></dependency><!-- pdf轉(zhuǎn)圖片 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>2.2 模板
注意 如果要?jiǎng)討B(tài)替換圖片需要先在模板里插入一張圖片,否則無法替換圖片
選中頭像后的圖片
2.3 邏輯代碼
public static void main(String[] args) {Map<String, Object> param = new HashMap<>();param.put("user.username", "小明不怕不怕啦");param.put("user.hobby", "愛玩dota");param.put("name", "sssssssssssssssssssssss");String rootPath = XdocreportUtils.class.getClassLoader().getResource("").getPath();String filePath = String.format("%stemplates/xdocreport/xdocxtemplate.docx", rootPath);Map<String, IImageProvider> imgMap = new HashMap<>();IImageProvider logo = new FileImageProvider(new File("C:\\Users\\Administrator\\Desktop\\2021122211591833953227008.png"), true);logo.setSize(500f, 500f);imgMap.put("logo", logo);IImageProvider pic = new FileImageProvider(new File("C:\\Users\\Administrator\\Desktop\\suoluePic.PNG"), true);pic.setSize(200f, 200f);imgMap.put("pic", pic);exportDocx(param, imgMap, new File(filePath), "C:\\Users\\Administrator\\Desktop\\DocxProjectWithFreemarker_Out.docx");exportPdf(param, imgMap, new File(filePath), "C:\\Users\\Administrator\\Desktop\\DocxProjectWithFreemarker_Out.pdf");}public static void exportDocx(Map<String, Object> param, Map<String, IImageProvider> imgMap, File templateFIle, String outPath) {try {InputStream in = new FileInputStream(templateFIle);//載入模板IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);IContext context = report.createContext();//設(shè)置要替換的值if (MapUtils.isNotEmpty(param)) {for (Map.Entry<String, Object> entry : param.entrySet()) {context.put(entry.getKey(), entry.getValue());}}FieldsMetadata metadata = report.createFieldsMetadata();report.setFieldsMetadata(metadata);//替換圖片if (MapUtils.isNotEmpty(imgMap)) {for (Map.Entry<String, IImageProvider> entry : imgMap.entrySet()) {context.put(entry.getKey(), entry.getValue());metadata.addFieldAsImage(entry.getKey());}}report.setFieldsMetadata(metadata);OutputStream out = new FileOutputStream(new File(outPath));report.process(context, out);out.close();} catch (IOException e) {log.error("導(dǎo)出docx文件出現(xiàn)異常!", e);} catch (XDocReportException e) {log.error("導(dǎo)出docx文件出現(xiàn)異常!", e);}}public static void exportPdf(Map<String, Object> param, Map<String, IImageProvider> imgMap, File templateFIle, String outPath) {try {InputStream in = new FileInputStream(templateFIle);//載入模板IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);IContext context = report.createContext();//設(shè)置要替換的值if (MapUtils.isNotEmpty(param)) {for (Map.Entry<String, Object> entry : param.entrySet()) {context.put(entry.getKey(), entry.getValue());}}FieldsMetadata metadata = report.createFieldsMetadata();report.setFieldsMetadata(metadata);//替換圖片if (MapUtils.isNotEmpty(imgMap)) {for (Map.Entry<String, IImageProvider> entry : imgMap.entrySet()) {context.put(entry.getKey(), entry.getValue());metadata.addFieldAsImage(entry.getKey());}}report.setFieldsMetadata(metadata);OutputStream out = new FileOutputStream(new File(outPath));Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF);report.convert(context, options, out);out.close();} catch (IOException e) {log.error("導(dǎo)出pdf文件出現(xiàn)異常!", e);} catch (XDocReportException e) {log.error("導(dǎo)出pdf文件出現(xiàn)異常!", e);}}2.4 效果
3、冰藍(lán)科技的Spire
3.1 引入maven配置
<dependency><groupId>e-iceblue</groupId><artifactId>spire.doc.free</artifactId><version>3.9.0</version></dependency><repositories><repository><id>com.e-iceblue</id><url>https://repo.e-iceblue.cn/repository/maven-public/</url></repository></repositories>3.2 邏輯代碼
import com.spire.doc.Document; import com.spire.doc.FileFormat; import com.spire.doc.documents.BookmarksNavigator; import com.spire.doc.documents.Paragraph; import com.spire.doc.documents.TextBodyPart; import com.spire.doc.fields.DocPicture;import java.io.IOException; import java.util.HashMap; import java.util.Map;public class SpireWordPicTest {public static void main(String[] args) throws IOException {//加載Word文檔Document doc = new Document("C:\\Users\\Administrator\\Desktop\\testDocTemplates.docx");Map<String,String> mappings = new HashMap<>();mappings.put("username","小明");mappings.put("password","123456");/*** https://www.cnblogs.com/Yesi/p/11422349.html* 需要先在模板里設(shè)置書簽 然后替換**/for(Map.Entry<String,String > entry:mappings.entrySet()){doc.replace(String.format("${%s}",entry.getKey()),entry.getValue(), false, true);}//定位到指定書簽位置 設(shè)置二維碼BookmarksNavigator bookmarksNavigator = new BookmarksNavigator(doc);bookmarksNavigator.moveToBookmark("headerPng", true, true);Paragraph para= new Paragraph(doc);DocPicture docPicture = para.appendPicture("C:\\Users\\Administrator\\Desktop\\企業(yè)微信截圖_20211228152622.png");//設(shè)置圖片寬度docPicture.setWidth(110);//設(shè)置圖片高度docPicture.setHeight(110);TextBodyPart bodyPart = new TextBodyPart(doc);bodyPart.getBodyItems().add(para);bookmarksNavigator.replaceBookmarkContent(bodyPart);//保存文檔doc.saveToFile("C:\\Users\\Administrator\\Desktop\\ReplaceAllMatchedText.docx", FileFormat.Docx_2013);}冰藍(lán)科技的免費(fèi)版代碼執(zhí)行效率很低,不知道正式版怎么樣
https://www.e-iceblue.cn/spiredocforjava/spire-doc-for-java-program-guide-content.html
樣例代碼可參考 https://gitee.com/wahnn/SpringBootAll/tree/master/SpringBoot-xdocreportAndDocx4j
總結(jié)
以上是生活随笔為你收集整理的java生成docx文件、pdf文件、docx转pdf、docx转图片 pdf转图片工具的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker容器内安装wkhtmltox
- 下一篇: 火星探险问题 网络流