首先是环境准备,需要jacob-1.17-x64.dll,jacob-1.17-x86.dll,jacob.jar ,网上找一下,需要注意下jdk版本。还有服务器端需要单独装word转pdf插件。
因为只设置一遍ComThread,这个线程只启用了一次,常用业务需要使用pdf转化,所以线程常驻。i7笔记本测试大概首次启动花了5s,处理每个文件0.3s左右。
static ActiveXComponent app1 = null;
static Dispatch docs1=null;
public synchronized static void colseApp() {//多个实例,不知道这个操作支不支持多线程,先同步了再说。
try {//所有操作完关闭 需要注意下。wps不支持调用invoke("Quit",0 )。
app1.invoke("Quit",0 );
ComThread.Release();
}catch(Exception e) {
e.printStackTrace();
if(docs1!=null) {
docs1=null;
}
if(app1!=null) {
app1=null;
}
ComThread.quitMainSTA();
}
}
public synchronized static void init() {//多个实例,不知道这个操作支不支持多线程,先同步了再说。
if(app1==null) {
ComThread.InitMTA(true); // 注意设置这个参数,未设置之前每次运行,只要同时第二个人点了Dispatch.call()返回null
app1=new ActiveXComponent("Word.Application");
app1.setProperty("Visible", false);
docs1= app1.getProperty("Documents").toDispatch();
}
}
public String word2pdf(String source,String target){
String flag="success";
System.out.println("启动Word");
long start = System.currentTimeMillis();
System.out.println("打开文档" + source);
try {
init();
Dispatch doc=null;
synchronized (docs1) {
doc= Dispatch.call(docs1,//
"Open", //
source,// FileName
false,// ConfirmConversions
true // ReadOnly
).toDispatch();
System.out.println("转换文档到PDF " + target);
File tofile = new File(target);
if (tofile.exists()) {
tofile.delete();
}
Dispatch.call(doc,//
"SaveAs", //
target, // FileName
wdFormatPDF);
Dispatch.call(doc, "Close", false);
}
long end = System.currentTimeMillis();
System.out.println("转换完成..用时:" + (end - start) + "ms.");
} catch (Exception e) {
System.out.println("========Error:文档转换失败:" + e.getMessage());
flag="failure";
colseApp();
} finally {
}
return flag;
}
记第一次使用word2pdf,使用有点粗糙,如果还要快点的话,大概要使用线程池对 进行管理,然后任务分发下。
-----------------------------------------------------------2019-9-27-----------------------------------------------------------------------
用了一段时间,发现jacob有局限性。
1.必须要windows 环境
2.dll文件引用,只在绿色版tomcat启动调用成功过。
3.开启多个进程进行 word\pdf\excel文件轮流切换转化时,office部分进程会小概率崩溃(目前靠杀进程处理。。)
优点:
word\excel各种格式兼容性较好,只是处理word转化pdf部分还算稳定,性能还可以。
public class Word2Pdf extends Thread{
public static final ConcurrentHashMap
new ConcurrentHashMap
public static final ConcurrentHashMap
new ConcurrentHashMap
public static final ConcurrentHashMap
new ConcurrentHashMap
private static final Stack
new Stack
private static final Logger LOG=Logger.getLogger(Word2Pdf.class);
//private static volatile boolean isLoad=false;
static final Object WORDLOCK=new Object();
/**
* // 作为type格式保存到临时文件
// *Variant(0):doc
// *Variant(1):dot
// *Variant(2-5),Variant(7):txt
// *Variant(6):rft
// *Variant(8),Variant(10):htm
// *Variant(9):mht
// *Variant(11),Variant(19-22):xml
// *Variant(12):docx
// *Variant(13):docm
// *Variant(14):dotx
// *Variant(15):dotm
// *Variant(16)、Variant(24):docx
// *Variant(17):pdf
// *Variant(18):xps
// *Variant(23):odt
// *Variant(25):与Office2003与2007的转换程序相关,执行本程序后弹出一个警告框说是需要更高版本的 Microsoft
*/
/**
* 加载jacob.dll
*/
public static void loadDll() {
/*if(!isLoad) {
try {
String path = Thread.currentThread().getContextClassLoader().getResource("/").getPath().substring(1);
System.out.println(path+"dll/jacob-1.17-M2-x64.dll");
System.load(path+"dll/jacob-1.17-M2-x64.dll");
}catch(Exception e) {
e.printStackTrace();
}
isLoad=true;
}*/
}
/**
* 清理word进程
*/
public void clearWord() {
closeThread("cmd /c taskkill /f /t /im werfault.exe");
closeThread("cmd /c taskkill /f /t /im WINWORD.EXE");
closeThread("cmd /c taskkill /f /t /im EXCEL.EXE");
closeThread("cmd /c taskkill /f /t /im POWERPNT.EXE");
WORDMAP.clear();
EXCELMAP.clear();
}
/**
* 测试
*/
public static void main(String[] args){
Word2Pdf word = new Word2Pdf();
word.wordtoDoc("E:\\1.doc","E:\\1.docx");
}
/**
* 关闭word
*/
public static void colseWord(int type) {
synchronized(WORDLOCK) {
try {// 所有操作完关闭
LOG.info("关闭word");
if(type==1) {
((ActiveXComponent) WORDMAP.get("app")).invoke("Quit", new Variant[0]);
WORDMAP.remove("app");
}
if(type==2) {
((ActiveXComponent) WORDMAP.get("app2")).invoke("Quit", new Variant[0]);
WORDMAP.remove("app2");
}
if(type==3) {
((ActiveXComponent) WORDMAP.get("app3")).invoke("Quit", new Variant[0]);
WORDMAP.remove("app3");
}
} catch (Exception e) {
e.printStackTrace();
LOG.error("关闭异常"+e.getMessage());
closeThread("cmd /c taskkill /f /t /im werfault.exe");
WORDMAP.clear();
closeThread("cmd /c taskkill /f /t /im WINWORD.EXE");
}
}
}
public static void clear() {
closeThread("cmd /c taskkill /f /t /im werfault.exe");
WORDMAP.clear();
closeThread("cmd /c taskkill /f /t /im WINWORD.EXE");
}
/**
* 关闭错误提示线程
*/
public static void closeThread(String cmd) {
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 关闭Excel
*/
public static void colseExcel() {
synchronized(WORDLOCK) {
try {
LOG.info("关闭Excel");
if(EXCELMAP!=null) {
((ActiveXComponent) EXCELMAP.get("app")).invoke("Quit", new Variant[0]);
}
}catch(Exception e) {
e.printStackTrace();
LOG.error("关闭异常"+e.getMessage());
/*ISRUNNING.removeAllElements();
ISRUNNING.add(false);*/
EXCELMAP.clear();
closeThread("cmd /c taskkill /f /t /im werfault.exe");
closeThread("cmd /c taskkill /f /t /im EXCEL.EXE");
}
}
}
/**
* 关闭PPT
*/
public static void colsePPT() {
synchronized(WORDLOCK) {
try {
LOG.info("关闭PPT");
if(PPTMAP!=null) {
((ActiveXComponent) PPTMAP.get("app")).invoke("Quit", new Variant[0]);
}
}catch(Exception e) {
e.printStackTrace();
LOG.error("关闭异常"+e.getMessage());
/*ISRUNNING.removeAllElements();
ISRUNNING.add(false);*/
PPTMAP.clear();
/*comThread.Release();*/
closeThread("cmd /c taskkill /f /t /im werfault.exe");
closeThread("cmd /c taskkill /f /t /im POWERPNT.EXE");
}
}
}
/**
* 根据类型初始类 WORDMAP word对象 EXCELMAP excel对象 true
*/
public synchronized static boolean init(List
//loadDll();
if(ISRUNNING==null||ISRUNNING.size()==0) {
ComThread.InitMTA(true);
ISRUNNING.add(true);
}
if(WORDMAP==null || WORDMAP.size()<3) {
HashMap
if(WORDMAP.get("app")==null) {
ActiveXComponent app=new ActiveXComponent("Word.Application");
app.setProperty("Visible", false);
map.put("app",app);
}
if(WORDMAP.get("app2")==null) {
ActiveXComponent app2=new ActiveXComponent("Word.Application");
app2.setProperty("Visible", false);
map.put("app2",app2);
}
if(WORDMAP.get("app3")==null) {
ActiveXComponent app3=new ActiveXComponent("Word.Application");
app3.setProperty("Visible", false);
map.put("app3",app3);
}
WORDMAP.putAll(map);
}
if(EXCELMAP==null || EXCELMAP.size()==0) {
HashMap
ActiveXComponent app=new ActiveXComponent("Excel.Application");
app.setProperty("Visible", false);
map.put("excel",app);
EXCELMAP.putAll(map);
}
return true;
}
/**
* 合并pdf
*
* @param files 文件路径列表
* @param savepath 输入文件路径
*/
public static void mergePdfFiles(String[] files, String savepath) {
try {
Document document = new Document(new PdfReader(files[0]).getPageSize(1));
PdfCopy copy = new PdfCopy(document, new FileOutputStream(savepath));
document.open();
for (int i = 0; i < files.length; i++) {
PdfReader reader = new PdfReader(files[i]);
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
}
document.close();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* word转pdf
*
* @param files 输入路径
* @param savepath 输出路径
*/
public String word2pdf(String source, String target) {
List
list.add(source);
if(!init(list)) {
return "failure";
};
return WordtoPdf.word2pdf(WORDMAP, source, target);
}
/**
* word转docx
*
* @param files 输入路径
* @param savepath 输出路径
*/
public String wordtoDoc(String source, String target) {
List
list.add(source);
if(!init(list)) {
return "failure";
};
return WordtoPdf.wordtoDoc(WORDMAP, source, target);
}
/**
* 合并word
* @param fileList
* @param target
* @return
*/
public String mergeWord(List
if(fileList.size()==0) {
return "failure";
}
if(!init(fileList)) {
return "failure";
};
return WordtoPdf.mergeWord(WORDMAP, fileList, target);
}
/**
* ppt转pdf
* @param source
* @param target
*/
public void ppt2pdf(String source, String target) {
List
list.add(source);
init(list);
PpttoPdf.ppt2pdf(PPTMAP, source, target);
}
/**
* 转化excel为pdf
*
* @param source
* @param target
*/
public String excel2pdf(String source, String target) {
List
list.add(source);
if(!init(list)) {
return "failure";
};
return ExcelToPdf.excel2pdf(EXCELMAP, source, target);
}
/**
* 图片转pdf
*
* @param imgFilePath
* @param pdfFilePath
* @return
* @throws IOException
*/
public static boolean imgToPdf(String imgFilePath, String pdfFilePath) throws IOException {
File file = new File(imgFilePath);
if (file.exists()) {
Document document = new Document();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(pdfFilePath);
PdfWriter.getInstance(document, fos);
// 添加PDF文档的某些信息,比如作者,主题等等
document.addAuthor("ht");
document.addSubject("test pdf.");
// 设置文档的大小
document.setPageSize(PageSize.A4);
// 打开文档
document.open();
// 写入一段文字
// document.add(new Paragraph("JUST TEST ..."));
// 读取一个图片
Image image = Image.getInstance(imgFilePath);
float imageHeight = image.getScaledHeight();
float imageWidth = image.getScaledWidth();
int i = 0;
while (imageHeight > 830 || imageWidth > 830) { // 830 更改转换比
image.scalePercent(100 - i); // 100 缩放比
i++;
imageHeight = image.getScaledHeight();
imageWidth = image.getScaledWidth();
// System.out.println("imageHeight->"+imageHeight);
// System.out.println("imageWidth->"+imageWidth);
}
image.setAlignment(Image.ALIGN_CENTER);
// //设置图片的绝对位置
// image.setAbsolutePosition(0, 0);
// image.scaleAbsolute(500, 400);
// 插入一个图片
document.add(image);
} catch (DocumentException de) {
System.out.println(de.getMessage());
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
document.close();
fos.flush();
fos.close();
return true;
} else {
return false;
}
}
}
public class WordtoPdf extends Thread{
static final int wdDoNotSaveChanges = 0;// 不保存待定的更改。
static final int wdFormatPDF = 17;// word转PDF 格式
static final int ppSaveAsPDF = 32;// ppt 转PDF 格式
static final Object WORDTOPDF=new Object();
static final Object WORDTODOC=new Object();
static final Object mergeWord=new Object();
/**
* word转pdf
*
* @param files 输入路径
* @param savepath 输出路径
*/
public static String word2pdf(ConcurrentHashMap
Word2Pdf.closeThread("cmd /c taskkill /f /t /im werfault.exe");
synchronized(WORDTOPDF) {
Dispatch docs1=null;
String flag = "success";
System.out.println("启动Word");
long start = System.currentTimeMillis();
System.out.println("打开文档" + source);
Dispatch doc = null;
try {
docs1=((ActiveXComponent) map.get("app")).getProperty("Documents").toDispatch();
doc = Dispatch.call(docs1, //
"Open", //
source, // FileName
false, // ConfirmConversions
true // ReadOnly
).toDispatch();
// Dispatch doc = Dispatch.call(docs, "Open",new Variant(source)).toDispatch();
// Dispatch doc = Dispatch.invoke(docs,"Open",Dispatch.Method,new
// Object[]{source},new int[17]).toDispatch();
System.out.println("转换文档到PDF " + target);
File tofile = new File(target);
if (tofile.exists()) {
tofile.delete();
}
tofile=null;
Dispatch.call(doc, //
"SaveAs", //
target, // FileName
wdFormatPDF);
// Dispatch.invoke(doc,"SaveAs",Dispatch.Method,new Object[]{target},new
// int[17]);
long end = System.currentTimeMillis();
System.out.println("转换完成..用时:" + (end - start) + "ms.");
} catch (Exception e) {
System.out.println("========Error:文档转换失败:" + e.getMessage());
flag = "failure";
} finally {
try {
if(doc != null) {
Dispatch.call(doc, "Close", new Variant(false));
doc.safeRelease();
doc=null;
}
if(docs1!=null) {
docs1.safeRelease();
docs1=null;
}
}catch(Exception e) {
Word2Pdf.colseWord(1);
e.printStackTrace();
}
//ComThread.Release();
}
return flag;
}
}
public static String wordtoDoc(ConcurrentHashMap
Word2Pdf.closeThread("cmd /c taskkill /f /t /im werfault.exe");
synchronized(WORDTOPDF) {
Dispatch docs1=null;
String flag = "success";
System.out.println("启动Word");
long start = System.currentTimeMillis();
System.out.println("打开文档" + source);
Dispatch doc = null;
try {
docs1=((ActiveXComponent) map.get("app2")).getProperty("Documents").toDispatch();
doc = Dispatch.call(docs1, //
"Open", //
source, // FileName
false, // ConfirmConversions
true // ReadOnly
).toDispatch();
// Dispatch doc = Dispatch.call(docs, "Open",new Variant(source)).toDispatch();
// Dispatch doc = Dispatch.invoke(docs,"Open",Dispatch.Method,new
// Object[]{source},new int[17]).toDispatch();
System.out.println("转换文档到PDF " + target);
File tofile = new File(target);
if (tofile.exists()) {
tofile.delete();
}
tofile=null;
Dispatch.call(doc, //
"SaveAs", //
target, // FileName
12);
// Dispatch.invoke(doc,"SaveAs",Dispatch.Method,new Object[]{target},new
// int[17]);
long end = System.currentTimeMillis();
System.out.println("转换完成..用时:" + (end - start) + "ms.");
} catch (Exception e) {
System.out.println("========Error:文档转换失败:" + e.getMessage());
flag = "failure";
} finally {
try {
if(doc != null) {
Dispatch.call(doc, "Close", new Variant(false));
}
}catch(Exception e) {
Word2Pdf.colseWord(2);
e.printStackTrace();
}
//ComThread.Release();
}
return flag;
}
}
/**
* 合并word doc
* @param map
* @param fileList
* @param target
* @return
*/
public static String mergeWord(ConcurrentHashMap
Word2Pdf.closeThread("cmd /c taskkill /f /t /im werfault.exe");
synchronized(mergeWord) {
Dispatch docs1=null;
Dispatch docs2=null;
String flag = "success";
System.out.println("启动Word");
long start = System.currentTimeMillis();
System.out.println("打开文档" + fileList.toString());
ActiveXComponent app=(ActiveXComponent) map.get("app3");
Dispatch doc = null;
try {
docs1=app.getProperty("Documents").toDispatch();
doc = Dispatch.call(docs1, //
"Open", //
(String) fileList.get(0), // FileName 最后一个文件
false, // ConfirmConversions
true // ReadOnly
).toDispatch();
// 追加文件
docs2=Dispatch.get(app, "Selection").toDispatch();
for (int i = 1; i < fileList.size(); i++) {
Dispatch.invoke(docs2,
"insertFile", Dispatch.Method, new Object[] {
(String) fileList.get(i), "",
new Variant(false), new Variant(false),
new Variant(true) }, new int[3]);
}
Dispatch.call(docs2, "InsertBreak" , new Variant(7) );
/*
* 插入分页符
* 若不插入,则直接将文件按顺序拼接成一个word
* 若插入分页符则添加了一个分页符号 变成了多页
*/
System.out.println("转换文档到word " + target);
File tofile = new File(target);
if (tofile.exists()) {
tofile.delete();
}
tofile=null;
Dispatch.call(doc, //
"SaveAs", //
target, // FileName
16);//docx格式不卡
long end = System.currentTimeMillis();
System.out.println("转换完成..用时:" + (end - start) + "ms.");
} catch (Exception e) {
System.out.println("========Error:文档转换失败:" + e.getMessage());
flag = "failure";
} finally {
try {
if(doc != null) {
Dispatch.call(doc, "Close", new Variant(false));
doc.safeRelease();
doc=null;
}
if(docs2 !=null) {
docs2.safeRelease();
docs2=null;
}
if(docs1 !=null) {
docs1.safeRelease();
docs1=null;
}
}catch(Exception e) {
Word2Pdf.colseWord(3);
e.printStackTrace();
}
//ComThread.Release();
}
return flag;
}
}
}