web中的jacob运用(包括使用itext为word加水印)

使用jacob的demo我在上一篇文章中已经做了笔记,接下来在这里我要记录jacob在web应用中的使用,同时也使用了itext为pdf添加水水印,框架为了方便使用的ssm框架。

搭建ssm框架这里就不做详细的介绍了,在我的博客中有这篇文章,详见http://www.cnblogs.com/advanceBlog/p/7858584.html

首先编写工具类word2PdfUtil.java,其中包括了word转pdf方法和itext加水印方法,代码如下:

package com.advance.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.lowagie.text.BadElementException;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;

public class Word2PdfUtil {
    static final int wdFormatPDF = 17;// word转PDF 格式 
    private final static float imageFillOpacity = 0.3f;//图片水印透明度
    private final static float imageScalePercent = 70;//水印图片缩放百分比
    private final static float imagePositionX = 80;//水印图片距离本页最左方的数据
    private final static float imagePositionY = 130;//水印图片距离本页最下方的数据
    public static void word2pdf(String source, String target) { 
        //初始化进程
        ComThread.InitMTA(true); 
        ActiveXComponent app = null;  
        Dispatch docs = null;
        Dispatch doc = null;
        try {  
            app = new ActiveXComponent("Word.Application");  
            app.setProperty("Visible", false);  
            docs = app.getProperty("Documents").toDispatch();  
            doc = Dispatch.call(docs, "Open", source, false, true).toDispatch();  
            File tofile = new File(target);  
            deleteFile(tofile.getName());
            Dispatch.call(doc, "SaveAs", target, wdFormatPDF);  
            Dispatch.call(doc, "Close", false);  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            //释放资源
            if(doc != null){
                doc.safeRelease();
            }
            if(docs != null){
                docs.safeRelease();
            }
            if (app != null) {  
                app.invoke("Quit", 0); 
                app.safeRelease();
            }  
            //关闭进程
            ComThread.Release();
        }  
    }  
    
    public static int addWaterMarker(String inputPdfPath,String code,String imagePath,String outPdfPath) throws Exception, IOException{
         // 待加水印的文件  
        PdfReader reader = null;
        Rectangle pageSize =  null;
        try {
            reader = new PdfReader(  
                    inputPdfPath);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  
        // 加完水印的文件  
        PdfStamper stamper = null;
        try {
            stamper = new PdfStamper(reader, new FileOutputStream(  
                    outPdfPath));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  
          
        int total = reader.getNumberOfPages() + 1; 
        PdfContentByte content = null;
        PdfContentByte under = null;
        BaseFont font = BaseFont.createFont("C://WINDOWS/Fonts/SIMSUN.TTC,1", "Identity-H",true);
        char c = 0;
        int rise = 0;
        int j = code.length();
        Image image = null;
        try {
            image = Image.getInstance(imagePath);
        } catch (BadElementException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 循环对每页插入水印  
        for (int i = 1; i < total; i++) {
            //添加文字水印
            rise = 400;
            under = stamper.getUnderContent(i);
            pageSize = reader.getPageSize(i);  
            float  marginTop = pageSize.getHeight()/2-20;  
            float marginLeft = pageSize.getWidth()-code.length()*14; 
            float imagePositionX = pageSize.getWidth()/2 - image.getWidth()/2;
            float imagePositionY = pageSize.getHeight()/2 - image.getHeight()/2;
            image.setAbsolutePosition(imagePositionX, imagePositionY);
            image.scalePercent(imageScalePercent);
            under.beginText();
            //设置合同编号水印字体字号
            under.setFontAndSize(font,14);
            //合同编号水印位置调整,参考图片水印位置
            under.setTextMatrix(marginLeft, marginTop);
            for(int k = 0;k < j;k++){
                under.setTextRise(rise);
                c=code.charAt(k);
                under.showText(c+"");
            }
            under.endText();
            // 圖片水印的起始  
            content = stamper.getOverContent(i);  
            //设置透明度
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(imageFillOpacity);
            content.setGState(gs);
            try {
                content.addImage(image);
            } catch (DocumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            content.endText();  
        }  
        try {
            stamper.close();
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        deleteFile(inputPdfPath);
        return total;
    }
    public static void deleteFile(String fileName) throws Exception{
        File file = new File(fileName);
        if (file.exists() && file.isFile()) {
            file.delete();
        } 
    }

}

然后编写controller方法IndexController.java,其中包含了上传以及下载方法(我为了偷懒,将创建文件夹的方法在controller中创建了,这个不符合规范),代码如下:

package com.advance.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.UUID;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.advance.util.Word2PdfUtil;

@Controller
public class IndexController {
    
    private final static String savePDFPath = "C://upload/PDF";
    private final static String tempPath = "C://upload/TEMP";
    private final static String imgPath = "C://upload/PDF/IMG";
    static{
        File savePDFDir = new File(savePDFPath);
        File tempDir = new File(tempPath);
        File imgDir = new File(imgPath);
        if(!savePDFDir.exists()){
            savePDFDir.mkdirs();
        }
        if(!tempDir.exists()){
            tempDir.mkdirs();
        }
        if(!imgDir.exists()){
            imgDir.mkdirs();
        }
    }
    
    @RequestMapping("/index.html")
    public String index(HttpServletRequest request){
        return "index";
    }
    
    @RequestMapping("/Word2PdfPage.html")
    public String toPage(HttpServletRequest request,String PDFName){
        if(PDFName != "" && PDFName != null){            
            request.setAttribute("PDFName", PDFName);
        }
        return "word2Pdf";
    }
    
    /**
     * 仅仅是word转pdf
     * @param file
     * @return
     * @throws Exception
     */
    @RequestMapping("/convertPdf.html")
    public String doConvert(@RequestParam("file")MultipartFile file,HttpServletRequest request) throws Exception{
        String oriName = file.getOriginalFilename();
        String toPath = tempPath+"/"+oriName;
        file.transferTo(new File(toPath));
        String PDFName = UUID.randomUUID().toString()+".pdf";
        String PDFPath = savePDFPath+"/"+PDFName;
        Word2PdfUtil.word2pdf(toPath, PDFPath);
//        Word2PdfUtil.addWaterMarker(PDFTempFilePath, "哈哈哈", "C://Users/advance/Desktop/a.jpg", savePath+"/"+UUID.randomUUID().toString()+".pdf");
        Word2PdfUtil.deleteFile(toPath);
//        Word2PdfUtil.deleteFile(PDFTempFilePath);
        return "redirect:Word2PdfPage.html?PDFName="+PDFName;
    }
    
    @RequestMapping("/Word2PdfAddWaterMakerPage.html")
    public String Word2PdfAddWaterMakerPage(HttpServletRequest request,String PDFName){
        if(PDFName != "" && PDFName != null){            
            request.setAttribute("PDFName", PDFName);
        }
        return "word2PdfAddMarker";
    }
    
    @RequestMapping("/convertPdfAddWaterMarker.html")
    public String convertPdfAddWaterMarker(@RequestParam("file")MultipartFile file,@RequestParam("img")MultipartFile img,HttpServletRequest request) throws Exception{
        String code = request.getParameter("code");
        //上传图片
        String imgOriName = img.getOriginalFilename();
        String toImgPath = imgPath+"/"+imgOriName;
        img.transferTo(new File(toImgPath));
        //上传文件
        String oriName = file.getOriginalFilename();
        String toPath = tempPath+"/"+oriName;
        file.transferTo(new File(toPath));
        String PDFTempName = UUID.randomUUID().toString()+".pdf";
        String PDFTempPath = savePDFPath+"/"+PDFTempName;
        Word2PdfUtil.word2pdf(toPath, PDFTempPath);
        String PDFName = UUID.randomUUID().toString()+".pdf";
        Word2PdfUtil.addWaterMarker(PDFTempPath, code, toImgPath, savePDFPath+"/"+PDFName);
        Word2PdfUtil.deleteFile(toImgPath);
        Word2PdfUtil.deleteFile(toPath);
        Word2PdfUtil.deleteFile(PDFTempPath);
        return "redirect:Word2PdfAddWaterMakerPage.html?PDFName="+PDFName;
    }
    
    @RequestMapping("/download.html")
    public ResponseEntity<byte[]> download(String name) throws IOException{
        byte[] file = null;
        InputStream in = new FileInputStream(savePDFPath+"/"+name);
        try {
            file = new byte[in.available()];
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            in.read(file);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        HttpHeaders headers = new HttpHeaders();
        try {
            headers.add("Content-Disposition", "attachment;filename="+new String(name.getBytes("gbk"),"iso-8859-1"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        in.close();
        HttpStatus statusCode = HttpStatus.OK;
        ResponseEntity<byte[]> response = new ResponseEntity<>(file,headers, statusCode);
        return response;
    }
    
}

这其中也碰到了很多问题:

1,如果你装的是wps的话,如果报错信息为 Can't get object clsid from progid的话,这个时候需要将wps卸载换成word;

2.若报错信息为Invoke of: SaveAs
        Source: Microsoft Word
         Description: 命令失败
的话,那么你还需要安装一个插件SaveAsPDFandXPS.exe,office的官网有提供,地址为https://www.microsoft.com/zh-cn/download/details.aspx?id=7
3.还有一个很奇怪的错误,com.jacob.com.ComFailException: VariantChangeType failed ,如果出现这个错误的话,那就是需要在你的C:WindowsSystem32configsystemprofile与C:WindowsSysWOW64configsystemprofile与下创建文件夹Desktop

4.在使用时,一定要记得关闭你的进程以及释放资源,要不然很严重的,有可能会导致错误:jacob Can't co-create object

当然如果报错信息为缺少dll文件的话那就是你没有将dll文件正确的放入到你使用jdk的jre的bin目录下。这个错误信息有很多,需要慢慢调试,千万不能心浮气躁。

演示地址:http://123.206.191.42:8080/word2Pdf/index.html

原文地址:https://www.cnblogs.com/advanceBlog/p/8781836.html