注意:com的線程回收不由java垃圾回收器進行處理,因此,每new一次jacob提供的類就要分配一定大小的內存給該操作,new出來的這個com對象在使用結束之后產生的垃圾java是無法回收的,new出來的對象越來越多,內存溢出就不可避免了
https://blog.csdn.net/u011783999/article/details/50897672?tdsourcetag=s_pcqq_aiomsg
https://men4661273.iteye.com/blog/2097871
參考路徑:
https://blog.csdn.net/csdnFlyFun/article/details/79523262#commentBox
Jacob組件下載地址:https://sourceforge.net/projects/jacob-project/
Jacob 介紹
Jacob 是 JAVA-COM Bridge的縮寫,是一個中間件,能夠提供自動化訪問MS系統下COM組件和Win32 libraries的功能。
MS系統提供的COM組件
COM組件 | 對象ID |
Microsoft Word | Word.Application |
Microsoft Excel | Excel.Application |
Microsoft Powerpoint | Powerpoint.Application |
Microsoft IE | InternetExplore.Application |
WPS文字 | KWPS.Aplication |
WPS的Excel | KET.Application |
WPS的演示文檔 | KWPP.Application |
核心類:
JacobObject:用於Java程序MS下的COM進行通信,創建標准的API框架
ComThread:初始化COM組件線程,釋放線程,對線程進行管理
Dispatch:調度處理類,封裝了操作來從而操作Office,並表示不同MS級別調度對象
ActiveXComponent : 創建COM組件
Variant : 與COM通訊的參數或者返回值
ROT :Running Object Table (ROT),運行對象表將每個線程映射到所有jacobobjects,在線程創建
核心方法:
Dispatch : 可調用該自動化對象的屬性或方法,具體的屬性和方法要看參考文檔VBA API
Dispatch.get(dispatch, String name);獲取對象屬性
Dispatch.put(dispatch, String name, Object value);設置對象屬性
Dispatch.call(dispatch, String name, Object… args);調用對象方法
Dispatch.call部分參數解釋:
Dispatch content = Dispatch.call(document, "XXX").getDispatch();
XXX所表示:
Documents:所有文檔
Open:打開文檔
ActiveXComponent.Visible:設置編輯器是否可見
Tables:獲得所有的表格
Bookmarks:所有標簽
Selection:光標所在處或選中的區域
select:選中
typeParagraph:設置為一個段落
ParagraphFormat:段落格式,用alignment設置
alignment:1、居中,2、靠右,3、靠左
Add:新建一個word文檔
Close:關閉文檔,0不保存,-1保存,-2彈出框確認,注意ComThread.Release();關閉整個word進程
SaveAS:另存為
save:保存
printOut:打印
Application:得到ActiveXComponent的實例
WindowState:Application的屬性,表示窗口的大小,0、default,1、maximize,2、minimize
top、left、height、width:application的屬性,表示窗口的位置
ActiveXComponent.Quit:關閉所有word文檔,但是不退出整個word程序
Range:表示文檔中的一個連續范圍,由一個起始字符位置和一個終止字符位置定義,進而可以得到格式的信息
Item:得到指定的表格
Rows:得到表格的所有行
Cell:表格的一個單元格
Text:word的文本內容
InsertFile:插入文件
InsertRowsBelow:在指定的行下面插入一行
InsertAfter:在指定對象后插入
Delete:刪除,可以是表格的行
Count:返回數目,比如Rows、Tables的數目
Height:返回高度,比如行高、表格行的高
Split:拆分單元格,要指定行數和列數
Merge:合並單元格
Exists:指定的對象是否存在,返回bool值
Copy:復制
Paste:粘貼
Font:字體
Name:字體的名字
Bold:字體是否為粗體
Italic:字體是否為斜體
Underline:字體是否有下划線
Color:顏色
Size:大小
Borders:指定邊框,-1為上邊框,-2左邊框,-3為下邊框,-4有右邊框,-5為橫向邊框,-6為縱向邊框,-7從左上角開始的斜線,-8從左下角開始的斜線
AutoFitBehavior:自動調整大小,1為內容自動調整大小,2為窗口自動調整大小
Content:取的內容
InLineShapes:
AddPicture:增加一張圖片,需要制定路徑
homeKey:光標移到開頭
moveDown:光標往下一行
moveUp:光標往上一行
moveRight:光標往左一列
moveLeft:光標往右一列
find:要查找的文本
Forward:向前查找
Format:查找的文本格式
MatchCase:大小寫匹配
MatchWholeWord:全字匹配
Execute:開始執行查找
參考:

import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Image; import com.itextpdf.text.PageSize; import com.itextpdf.text.pdf.PdfWriter; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComFailException; import com.jacob.com.ComThread; import com.jacob.com.Dispatch; import com.jacob.com.Variant; public class JacobPDFConverter implements PDFConverter { private static final int wdFormatPDF = 17; private static final int xlTypePDF = 0; private static final int ppSaveAsPDF = 32; public void convert2PDF(String inputFile, String pdfFile) { String suffix = FileUtils.getFileSufix(inputFile); File file = new File(inputFile); if(!file.exists()){ System.out.println("文件不存在!"); return; } if(suffix.equals("pdf")){ System.out.println("PDF not need to convert!"); return ; } boolean isImg = false;//FileUtils.isImage(inputFile); try{ isImg = FileUtils.isImage(inputFile); }catch(Exception ce){ } if(isImg){ img2PDF(inputFile,pdfFile); }else if(suffix.equals("doc")||suffix.equals("docx")||suffix.equals("txt")){ word2PDF(inputFile,pdfFile); }else if(suffix.equals("ppt")||suffix.equals("pptx")){ ppt2PDF(inputFile,pdfFile); }else if(suffix.equals("xls")||suffix.equals("xlsx")){ excel2PDF(inputFile,pdfFile); }else if(suffix.equals("wps")){ //wps2PDF(inputFile,pdfFile); word2PDF(inputFile,pdfFile); }else{ //System.out.println("文件格式不支持轉換!"); word2PDF(inputFile,pdfFile); } } public void convert2PDF(String inputFile) { String pdfFile = FileUtils.getFilePrefix(inputFile)+".pdf"; convert2PDF(inputFile,pdfFile); } public void convert2PDF(String[] inputFiles, String[] pdfFiles) { try { for(int i = 0;i<inputFiles.length;i++){ String inputFile = inputFiles[i]; String pdfFile = pdfFiles[i]; if(inputFile==null || inputFile.equals("")) continue; convert2PDF(inputFile,pdfFile); } }catch (Exception ce) { } } public void convert2PDF(String[] inputFiles) { String pdfFiles[] = new String[inputFiles.length]; for(int i = 0;i<inputFiles.length;i++){ String inputFile = inputFiles[i]; String pdfFile = FileUtils.getFilePrefix(inputFile)+".pdf"; pdfFiles[i] = pdfFile; } convert2PDF(inputFiles,pdfFiles); } public static void word2PDF(String inputFile,String pdfFile){ ActiveXComponent app = null; Dispatch doc = null; try { ComThread.InitSTA(); app = new ActiveXComponent("Word.Application"); //打開word應用程序 app.setProperty("Visible", false); //設置word不可見 Dispatch docs = app.getProperty("Documents").toDispatch(); //獲得word中所有打開的文檔,返回Documents對象 //調用Documents對象中Open方法打開文檔,並返回打開的文檔對象Document doc = Dispatch.call(docs, "Open", inputFile, false, true ).toDispatch(); Dispatch.call(doc, "ExportAsFixedFormat", pdfFile, wdFormatPDF //word保存為pdf格式宏,值為17 ); } catch (ComFailException e) { } catch (Exception e) { } finally { if (doc != null) { Dispatch.call(doc, "Close", false); //關閉文檔 } if (app != null) { app.invoke("Quit", 0); //關閉word應用程序 } ComThread.Release(); } } public static void excel2PDF(String inputFile,String pdfFile){ ActiveXComponent app = null; Dispatch excel = null; try { ComThread.InitSTA(); app = new ActiveXComponent("Excel.Application"); app.setProperty("Visible", false); Dispatch excels = app.getProperty("Workbooks").toDispatch(); excel = Dispatch.call(excels, "Open", inputFile, false, true ).toDispatch(); Dispatch.call(excel, "ExportAsFixedFormat", xlTypePDF, pdfFile ); } catch (ComFailException e) { } catch (Exception e) { } finally { if (excel != null) { Dispatch.call(excel, "Close",false); } if (app != null) { app.invoke("Quit"); } ComThread.Release(); } } public static void ppt2PDF(String inputFile,String pdfFile){ ActiveXComponent app = null; Dispatch ppt = null; try { ComThread.InitSTA(); app = new ActiveXComponent("PowerPoint.Application"); //app.setProperty("Visible", false); Dispatch ppts = app.getProperty("Presentations").toDispatch(); ppt = Dispatch.call(ppts, "Open", inputFile, true,//ReadOnly true,//Untitled指定文件是否有標題 false//WithWindow指定文件是否可見 ).toDispatch(); Dispatch.call(ppt, "SaveAs", pdfFile, ppSaveAsPDF ); } catch (ComFailException e) { System.out.println(e.getMessage()); } catch (Exception e) { } finally { if (ppt != null) { Dispatch.call(ppt, "Close"); } if (app != null) { app.invoke("Quit"); } ComThread.Release(); } } public void wps2PDF(String inputFile,String pdfFile) { File sFile = new File(inputFile); File tFile = new File(pdfFile); ActiveXComponent wps = null; try { ComThread.InitSTA(); wps = new ActiveXComponent("wps.application"); ActiveXComponent doc = wps.invokeGetComponent("Documents").invokeGetComponent("Open", new Variant(sFile.getAbsolutePath())); doc.invoke("ExportPdf", new Variant(tFile.getAbsolutePath())); doc.invoke("Close"); doc.safeRelease(); } catch (Exception e) { System.out.println(e.getMessage()); } finally { if (wps != null) { wps.invoke("Terminate"); wps.safeRelease(); } ComThread.Release(); } } public void img2PDF(String inputFile,String pdfFile) { Document doc = new Document(PageSize.A4, 20, 20, 20, 20); try { PdfWriter.getInstance(doc, new FileOutputStream(pdfFile)); doc.open(); doc.newPage(); Image img = Image.getInstance(inputFile); float heigth = img.getHeight(); float width = img.getWidth(); int percent = getPercent(heigth, width); img.setAlignment(Image.MIDDLE); img.scalePercent(percent+3);// 表示是原來圖像的比例; doc.add(img); doc.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } File mOutputPdfFile = new File(pdfFile); if (!mOutputPdfFile.exists()) { mOutputPdfFile.deleteOnExit(); return; } } public static int getPercent(float h, float w) { int p = 0; float p2 = 0.0f; p2 = 530 / w * 100; p = Math.round(p2); return p; } }
例:

package net.nblh.utils; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import org.icepdf.core.pobjects.Document; import org.icepdf.core.util.GraphicsRenderingHints; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComFailException; import com.jacob.com.ComThread; import com.jacob.com.Dispatch; import com.jacob.com.Variant; public class Word2PdfUtil { private static final int ppSaveAsPDF = 32; static final int wdDoNotSaveChanges = 0;// 不保存待定的更改 static final int wdFormatPDF = 17;// word轉PDF 格式 /** * 文檔轉pdf轉png * @param source 源文件 */ public static int execuConvert(String source) { String ext = source.substring(source.lastIndexOf(".")); String tar = source.replace(ext, ".pdf"); File file = new File(tar); if (file.exists()) { //pdf文件已轉換,直接轉png return pdf2pngByFile(tar); } // 示例 // String source = "D:\\2017\\庭審案件材料一.doc"; // String target = "D:\\2018\\庭審案件材料一.pdf"; if (!checkAvailable(source,tar)) { return 0; } // String t = setPdfType(source, target); String suffixStr = getSuffix(source); if (".doc".equals(suffixStr) || ".docx".equals(suffixStr)) { return word2pdf(source, tar); } else if(".pptx".equals(suffixStr) || ".ppt".equals(suffixStr)){ return ppt2pdf(source, tar); } else if(".xls".equals(suffixStr) || ".xlsx".equals(suffixStr)){ return xls2Pdf(source, tar); } else { System.out.println("無法轉換此文件格式"); } return 0; } public static int word2pdf(String source, String target) { ActiveXComponent app = null; Dispatch doc = null; try { app = new ActiveXComponent("Word.Application"); app.setProperty("Visible", false); Dispatch docs = app.getProperty("Documents").toDispatch(); doc = Dispatch.call(docs, "Open", source, false, true).toDispatch(); File tofile = new File(target); File dirPath = new File(getPath(target)); if (tofile.exists()) { tofile.delete(); } else if (!dirPath.exists()) { dirPath.mkdirs(); } Dispatch.call(doc, "SaveAs", target, wdFormatPDF); // Dispatch.call(doc, "SAs", target, wdFormatPDF); Dispatch.call(doc, "Close", false); doc = null; app.invoke("Quit", wdDoNotSaveChanges); app = null; System.out.println("pdf_ok"); return pdf2pngByFile(target); } catch (Exception e) { return 0; } finally { if (null != doc) { Dispatch.call(doc, "Close", false); } if (app != null) { app.invoke("Quit", wdDoNotSaveChanges); } } } /** * 檢查文件格式,只轉換doc ,docx,ppt格式 fileName 文件名 * * @return */ private static boolean checkFormat(String fileName) { if (null == fileName || "".equals(fileName)) { return false; } if (!(fileName.substring(fileName.lastIndexOf(File.separator)).contains("."))) { System.out.println("沒有指明要轉換的文件"); return false; } String format = fileName.substring(fileName.lastIndexOf(".")); if (".doc".equals(format) || ".docx".equals(format) || ".ppt".equals(format) || ".pptx".equals(format) || ".xls".equals(format) || ".xlsx".equals(format) || ".dot".equals(format) || ".dotx".equals(format) || ".pot".equals(format) || ".potx".equals(format) || ".xlt".equals(format) || "xltx".equals(format)) { return true; } System.out.println("文件格式不合符,無法轉換"); return false; } /** * 檢查路徑是否正確 * @return */ public static boolean checkAvailable(String source,String target){ if (isEmpty(source.trim())) { System.out.println("源文件路徑不存在"); return false; } if(!source.contains(File.separator) || !source.contains(".")){ System.out.println("請輸入正確的源文件路徑,以及源文件名"); return false; } if(".".equals(getSuffix(source).trim())){ System.out.println("請輸入正確的源文件名"); return false; } if(isEmpty(target)){ System.out.println("目標文件路徑不存在"); return false; } if(!target.contains(File.separator) || !target.contains(".")){ System.out.println("請輸入正確的目標文件路徑,以及目標文件名"); return false; } if(!".pdf".equals(getSuffix(target))){ System.out.println("請正確輸入要生成的pdf文件名"); return false; } return true; } /** * 截取文件全路徑,不包括文件名 F:/snd/down/ceshi/ */ private static String getPath(String fileName) { if (null != fileName || !"".equals(fileName)) { return fileName.substring(0, fileName.lastIndexOf(File.separator)); } return ""; } /** * 如果目標文件后綴名不是pdf,則強行改為pdf */ private static String setPdfType(String source, String target) { // 目標路徑包含文件名稱 if (target.substring(target.lastIndexOf(File.separator)).contains(".")) { String ext = target.substring(target.lastIndexOf(".")); String fileName = target.replace(ext, ".pdf"); return fileName; } else { // 沒有文件名稱,只有路徑 return target + getFileName(source) + ".pdf"; } } /** * 截取文件名 不包含后綴名 * * @return */ private static String getFileName(String fileName) { if (!isEmpty(fileName)) { return fileName.substring(fileName.lastIndexOf(File.separator), fileName.lastIndexOf(".")); } return ""; } /** * 獲得后綴名 * @param fileName * @return */ private static String getSuffix(String fileName){ return fileName.substring(fileName.lastIndexOf(".")); } private static boolean isEmpty(String str) { if (null == str || "".equals(str)) { return true; } return false; } //ppt 轉 pdf public static int ppt2pdf(String srcFilePath, String pdfFilePath) { ActiveXComponent app = null; Dispatch ppt = null; try { ComThread.InitSTA(); app = new ActiveXComponent("PowerPoint.Application"); Dispatch ppts = app.getProperty("Presentations").toDispatch(); // 因POWER.EXE的發布規則為同步,所以設置為同步發布 ppt = Dispatch.call(ppts, "Open", srcFilePath, true, // ReadOnly true, // Untitled指定文件是否有標題 false// WithWindow指定文件是否可見 ).toDispatch(); File dirPath = new File(getPath(pdfFilePath)); if (!dirPath.exists()) { dirPath.mkdirs(); } Dispatch.call(ppt, "SaveAs", pdfFilePath, ppSaveAsPDF); // ppSaveAsPDF為特定值32 System.out.println("pdf轉換完成!"); return pdf2pngByFile(pdfFilePath); // set flag true; } catch (ComFailException e) { System.out.println(e.toString()); return 0; } catch (Exception e) { System.out.println(e.toString()); return 0; } finally { if (ppt != null) { Dispatch.call(ppt, "Close"); } if (app != null) { app.invoke("Quit"); } ComThread.Release(); } } // EXCEL轉PDF public static int xls2Pdf(String inFilePath, String outFilePath) { ActiveXComponent ax = null; Dispatch excels = null; Dispatch excel = null; try { ax = new ActiveXComponent("Excel.Application"); ComThread.InitSTA(); ax.setProperty("Visible", new Variant(false)); ax.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏 excels = ax.getProperty("Workbooks").toDispatch(); File dirPath = new File(getPath(outFilePath)); if (!dirPath.exists()) { dirPath.mkdirs(); } excel = Dispatch .invoke(excels, "Open", Dispatch.Method, new Object[] { inFilePath, new Variant(false), new Variant(false) }, new int[9]) .toDispatch(); // 轉換格式 Dispatch.invoke(excel, "ExportAsFixedFormat", Dispatch.Method, new Object[] { new Variant(0), // PDF格式=0 outFilePath, new Variant(0) }, new int[1]);// 0=標准 // (生成的PDF圖片不會變模糊) // 1=最小文件 // (生成的PDF圖片糊的一塌糊塗) Dispatch.call(excel, "Close", new Variant(false)); if (ax != null) { ax.invoke("Quit", new Variant[] {}); ax = null; } System.out.println("pdf轉換完成!"); return pdf2pngByFile(outFilePath); } catch (Exception es) { System.out.println(es.toString()); return 0; } finally { ComThread.Release(); } } /** * 本地pdf文件轉png */ public static int pdf2pngByFile(String target){ String filePath = target; Document document = new Document(); // System.out.println("開始轉png"); try { document.setFile(filePath); float scale = 1.5f;// 縮放比例(大圖) // float scale = 0.2f;// 縮放比例(小圖) float rotation = 0f;// 旋轉角度 int pageSize = document.getNumberOfPages(); for (int i = 0; i < document.getNumberOfPages(); i++) { BufferedImage image = (BufferedImage) document.getPageImage(i, GraphicsRenderingHints.SCREEN, org.icepdf.core.pobjects.Page.BOUNDARY_CROPBOX, rotation, scale); RenderedImage rendImage = image; // try { // File file = new File("D:/fileUpload/ftpDownload/icepdf_a" + i + ".png"); // // 這里png作用是:格式是jpg但有png清晰度 // ImageIO.write(rendImage, "png", file); // } catch (IOException e) { // e.printStackTrace(); // } try { // WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext(); // ServletContext servletContext = webApplicationContext.getServletContext(); // File contextPath = new File(servletContext.getRealPath("/")); // 項目根目錄 // File uploadPath = new File( // contextPath.getParentFile().getAbsoluteFile() + File.separator + "uploadFiles"); // 上傳圖片存放目錄 File uploadPath = new File(target); String fileName = getPathWithName(target); File file1 = new File(fileName); if (!file1.exists()) { file1.mkdirs(); } // System.out.println("地址=" + uploadPath.getAbsolutePath() + "/icepdf_a" + i + ".png" + "\n"); File file = new File(fileName + "\\" + i + ".png"); // 這里png作用是:格式是jpg但有png清晰度 ImageIO.write(rendImage, "png", file); } catch (IOException e) { e.printStackTrace(); } image.flush(); } document.dispose(); System.out.println("png_ok"); System.out.println("pageSize="+pageSize); return pageSize; } catch (Exception e1) { e1.printStackTrace(); } return 0; } /** * 截取文件全路徑,包括文件名,去掉后綴 F:/snd/down/ceshi/aaa */ public static String getPathWithName(String fileName) { if (null != fileName || !"".equals(fileName)) { return fileName.substring(0, fileName.lastIndexOf(".")); } return ""; } }
ppt = Dispatch.call(ppts, "Open", srcFilePath, true, // ReadOnly false, // Untitled指定文件是否有標題(參數必須為false,設置成true,ppt轉換pdf異常) false// WithWindow指定文件是否可見 ).toDispatch(); Dispatch.call(ppt, "SaveAs", pdfFilePath, ppSaveAsPDF); // ppSaveAsPDF為特定值32
參考地址:
https://blog.csdn.net/u013761812/article/details/72742629
http://blog.sina.com.cn/s/blog_aa90e61e0101a14x.html
http://www.bubuko.com/infodetail-1320787.html