java-使用Jacob实现office转换成pdf

不羁岁月 提交于 2020-05-02 04:34:23

注意: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;
       }
}
View Code

 

例:

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 "";
    }

}
View Code

 

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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!