項目中須要將一段文字,與人員的簽名(圖片)插入到上傳的word中,上網查詢了一下,有許多種方式能夠向word中插入文字,發現docx4j與jacob都爲比較常見的解決方案,因而就先使用的docx4j進行了文字與圖片的插入,在本身開發的機器上docx4j插入文字與圖片均成功了,可是在部署到服務器上的時候,使用docx4j插入圖片的時候,一直出現一個圖片沒法插入的bug,沒有解決掉,因而就又使用的jacob進行嘗試,而後成功了。將兩種對word進行操做的工具進行一下總結。html
安裝: docx4j要簡單于jacob。docx4j只須要pom文件中添加便可,jacob須要pom添加後在本機jre的bin目錄下安裝一個dll文件。java
代碼量:二者使用同一功能的代碼量差很少。git
資料:百度下jacob的資料要比docx4j多一些,docx4j英文的資料多一些,在github下也能夠找到docx4j。github
docx4j安裝時候,只須要向pom中添加依賴便可。數組
pom文件:服務器
<groupId>org.docx4j</groupId> <artifactId>docx4j</artifactId> <version>3.3.1</version> </dependency>
/** * Method Description:使用docx4j插入圖片 * * @param templatePath * // 模板文件路徑 * @param targetPath * // 生成的文件路徑 * @param bookmarkName * // 書籤名 * @param imagePath * void // 圖片路徑 * @throws Exception * @Author: 張昊亮 * @Date: 2018年5月17日 下午4:17:20 */ public void insertPicture(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("CTBookmark", "CTMarkupRange"); new TraversalUtil(paragraphs, rt); // 遍歷書籤 for (CTBookmark bm : rt.getStarts()) { // 這兒能夠對單個書籤進行操做,也能夠用一個map對全部的書籤進行處理 if (bm.getName().equals(bookmarkName)) { // 讀入圖片並轉化爲字節數組,由於docx4j只能字節數組的方式插入圖片 InputStream is = new FileInputStream(imagePath); byte[] bytes = IOUtils.toByteArray(is); // 建立一個行內圖片 BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wPackage, bytes); // createImageInline函數的前四個參數我都沒有找到具體啥意思 // 最有一個是限制圖片的寬度,縮放的依據 Inline inline = imagePart.createImageInline(null, null, 0, 1, false, 800); // 獲取該書籤的父級段落 P p = (P) (bm.getParent()); ObjectFactory factory = new ObjectFactory(); // R對象是匿名的複雜類型,然而我並不知道具體啥意思,估計這個要好好去看看ooxml才知道 R run = factory.createR(); // drawing理解爲畫布 Drawing drawing = factory.createDrawing(); drawing.getAnchorOrInline().add(inline); run.getContent().add(drawing); p.getContent().add(run); } } wPackage.save(new FileOutputStream(targetPath)); }
/** * Method Description:使用docx4j插入文字 * * @param templatePath * //模板文件位置 * @param targetPath * //生成文件位置 * @param words * //添加的文字內容 * @param bookmarkName * //書籤名稱 * @throws Docx4JException * @throws FileNotFoundException * * @Author: 張昊亮 * @Date: 2018年5月21日 上午10:02:51 */ public void insertWords(String templatePath, String targetPath, String words, String bookmarkName) throws FileNotFoundException, Docx4JException { // 載入模板文件 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("CTBookmark", "CTMarkupRange"); new TraversalUtil(paragraphs, rt); // 遍歷書籤 for (CTBookmark bm : rt.getStarts()) { // 這兒能夠對單個書籤進行操做,也能夠用一個map對全部的書籤進行處理 if (bm.getName().equals(bookmarkName)) { ObjectFactory factory = new ObjectFactory(); P p = (P) (bm.getParent()); // 添加到了標籤處 R r = factory.createR(); Text t = new Text(); t.setValue(words); r.getContent().add(t); p.getContent().add(r); wPackage.getMainDocumentPart().getContent().add(p); } } wPackage.save(new FileOutputStream(targetPath)); }
jacob在安裝的時候須要,有jar包還有dll文件。app
jacob包文件下載:連接:https://pan.baidu.com/s/1v0ZYsVYSu_BO5rB252ufvA 密碼:mlfsmaven
<dependency> <groupId>com.jacob</groupId> <artifactId>jacob</artifactId> <version>1.18</version> </dependency>
maven項目,添加pom依賴後,須要將jacob-1.18-x64.dll 文件放入項目所在電腦的jre的bin目錄下,方可運行。函數
注:圖片在資料中沒有查詢到的在書籤位置插入,而是使用的用圖片去替換文字。工具
/** * Method Description:使用jacob插入圖片 * * @param templatePath * //模板文件位置 * @param targetPath * //生成文件位置 * @param word * // 查詢文字的地方 * @param imagePath * void // 圖片路徑 * * @Author: 張昊亮 * @Date: 2018年5月23日 下午4:18:27 */ public void insertPicByjacob(String templatePath, String targetPath, String word, String imagePath) { System.out.println("啓動word..."); ActiveXComponent app = null; Dispatch doc = null; // 模板的路徑 String openPath = templatePath; // 要保存的文件的路徑 String toFileName = targetPath; Dispatch docs = null; if (app == null || app.m_pDispatch == 0) { app = new ActiveXComponent("Word.Application"); app.setProperty("Visible", new Variant(false)); app.setProperty("DisplayAlerts", new Variant(false)); } if (docs == null) { // 得到documents對象 docs = app.getProperty("Documents").toDispatch(); } doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] { openPath, new Variant(false), new Variant(true) }, new int[1]) .toDispatch(); System.out.println("打開文檔..." + openPath); Dispatch selection = app.getProperty("Selection").toDispatch(); Dispatch find = Dispatch.call(selection, "Find").toDispatch();// 得到Find組件 Dispatch.put(find, "Text", word); // 查找字符串 Dispatch.put(find, "MatchWholeWord", "True"); // 全字匹配 boolean bl = Dispatch.call(find, "Execute").getBoolean(); // 執行查詢 if (bl) { Dispatch inLineShapes = Dispatch.get(selection, "InLineShapes").toDispatch(); Dispatch picture = Dispatch.call(inLineShapes, "AddPicture", imagePath).toDispatch(); } // 保存文件//new variant() 參數 0Doc 十二、16Docx 17pdf Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { targetPath, new Variant(12) }, new int[1]); Dispatch.call((Dispatch) doc, "Close", new Variant(false)); System.out.println("關閉文檔"); if (app != null) app.invoke("Quit", new Variant[] {}); }
/** * Method Description:使用jacob插入文字 * * @param templatePath * //模板文件位置 * @param targetPath * //生成文件位置 * @param words * //要插入的內容 * @param bookmarkName * void // 書籤名 * * @Author: 張昊亮 * @Date: 2018年5月24日 下午5:15:25 */ public void insertWordByjacob(String templatePath, String targetPath, String words, String bookmarkName) { System.out.println("啓動word..."); ActiveXComponent app = null; Dispatch doc = null; // 模板的路徑 String openPath = templatePath; // 要保存的文件的路徑 String toFileName = targetPath; Dispatch docs = null; if (app == null || app.m_pDispatch == 0) { app = new ActiveXComponent("Word.Application"); app.setProperty("Visible", new Variant(false)); app.setProperty("DisplayAlerts", new Variant(false)); } if (docs == null) { // 得到documents對象 docs = app.getProperty("Documents").toDispatch(); } doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] { openPath, new Variant(false), new Variant(true) }, new int[1]) .toDispatch(); System.out.println("打開文檔..." + openPath); Dispatch activeDocument = app.getProperty("ActiveDocument").toDispatch(); Dispatch bookMarks = app.call(activeDocument, "Bookmarks").toDispatch(); Dispatch rangeItem = Dispatch.call(bookMarks, "Item", bookmarkName).toDispatch(); Dispatch range = Dispatch.call(rangeItem, "Range").toDispatch(); Dispatch.put(range, "Text", new Variant(words)); // 保存文件//new variant() 參數 0Doc 十二、16Docx 17pdf Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { targetPath, new Variant(12) }, new int[1]); Dispatch.call((Dispatch) doc, "Close", new Variant(false)); System.out.println("關閉文檔"); if (app != null) app.invoke("Quit", new Variant[] {}); }