注意: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