java+jacob实现word转pdf(通过调用模板文件)

本文介绍如何使用Java和Jacob库将Word文档转换为PDF格式。通过具体代码示例展示了从准备环境到实现转换的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:日常开发ERP系统,会有一些工单或者合同之类需要填写打印。我们就会将其word模板来通过系统自动化填写并转换为PDF格式(PDF文件打印可保证文件质量,是一种通用的格式。文件不易去修改,比较稳定)。所以我们将通过jacob来实现这些功能。



准备工作:
1.服务器需要安装office2007,因为我们就是调用这个来实现转换。
2.需要安装插件jacob,安装jacob-1.14.3-x86.dll到jdk\jdk1.7.0\jre\bin(你自己电脑安装的jdk)
3.需要使用jacob-1.14.3.jar包
    maven代码如下: 
                <dependency>
		    <groupId>net.sf.jacob-project</groupId>
		    <artifactId>jacob</artifactId>
		    <version>1.14.3</version>
		</dependency>
4.假如通过以上准备工作未成功转换,就下载一个SaveAsPDFandXPS.exe组件(office2007里的)。我就是通过这个组件才完成转换。
5.上面的在系统为windows7中就可以了,假如你的项目需要发布到服务器(服务器系统一般都是windows2008)。则还需要一步。在上面的基础上再安装安装jacob-1.14.3-x64.dlljdk\jdk1.7.0\jre\bin(你自己电脑安装的jdk)中。很多人在win7下都能成功转换,但在win2008就是出问题。我就是通过磨了一天的时间,看了各种日志才发现问题。

一:工具类(OperationIo.java),这里面可以不做任何修改,复制粘贴就可以了。

package com.repair.util.pub;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class OperationIO {
	
	static final int wdFormatPDF = 17;// PDF 格式   
	/**
	 * WORD转换PDF
	 * @param sfileName WORD文件存在位置
	 * @param toFileName PDF文件存放位置
	 */ 	 
	public static void wordToPDF(String sfileName,String toFileName){    
        System.out.println("启动Word...");      
        long start = System.currentTimeMillis();   
        ActiveXComponent app = null;  
        Dispatch doc = null;  
        try {      
        	//调用office word
            app = new ActiveXComponent("Word.Application");      
            app.setProperty("Visible", new Variant(false));  
            Dispatch docs = app.getProperty("Documents").toDispatch();    
            doc = Dispatch.call(docs,  "Open" , sfileName).toDispatch();  
            System.out.println("打开文档..." + sfileName);  
            System.out.println("转换文档到PDF..." + toFileName);      
            File tofile = new File(toFileName);      
            if (tofile.exists()) {      
                tofile.delete();      
            }      
            Dispatch.call(doc,      
                          "SaveAs",      
                          toFileName, // FileName      
                          wdFormatPDF);      
            long end = System.currentTimeMillis();      
            System.out.println("转换完成..用时:" + (end - start) + "ms.");  
              
                
        } catch (Exception e) {      
            System.out.println("========Error:文档转换失败:" + e.getMessage());      
        } finally {  
            Dispatch.call(doc,"Close",false);  
            System.out.println("关闭文档");  
            if (app != null)      
                app.invoke("Quit", new Variant[] {});      
            }  
          //如果没有这句话,winword.exe进程将不会关闭  
           ComThread.Release();     
    }  
	
	/**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     *                 If a deletion fails, the method stops attempting to
     *                 delete and returns "false".
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return dir.delete();
    }
	/**
     * 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
     * @param imgFilePath 图片地址路径
     */
    public static String GetImageStr(String imgFilePath) {// 
        byte[] data = null;
         
        // 读取图片字节数组
        try {
          InputStream in = new FileInputStream(imgFilePath);
          data = new byte[in.available()];
          in.read(data);
          in.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
         
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);// 返回Base64编码过的字节数组字符串
      }
    
    
    /** 
     * 将二进制转换为图片 
     *  
     * @param base64String 
     */  
    public static void base64StringToImage(String base64String,String imageoutpath) {  
        try {  
        	BASE64Decoder decoder = new sun.misc.BASE64Decoder(); 
            byte[] bytes1 = decoder.decodeBuffer(base64String);  
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);  
            BufferedImage bi1 = ImageIO.read(bais);  
            File w2 = new File(imageoutpath);// 可以是jpg,png,gif格式  
            ImageIO.write(bi1, "jpg", w2);// 不管输出什么格式图片,此处不需改动  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}

二:业务类(PrintWordToPdf.java),这里
package com.hjm.Test;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import com.engineering.pojos.pub.gcRecordArchive;
import com.repair.util.pub.OperationIO;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class PrintWordToPdf {

	public static void main(String[] args) {
		//创建一个Configuration的实例
		Configuration configuration = new Configuration();
		//设置编码
		configuration.setDefaultEncoding("utf-8");
		//创建Map对象,来保存要填写的数据
		Map<String, Object> paraMap = new HashMap<String, Object>();
		//下面这些是我测试的一些数据
		paraMap.put("ReceivingParty", "中国民航");
		
		paraMap.put("PackingListNo", 10087);
		
		paraMap.put("ConNo", 10088);
		
		try {
			//调用模板的文件夹,new File("D:\\测试")是一个绝对路径,你可以自己设置为服务器路径。
			configuration.setDirectoryForTemplateLoading(new File("D:\\测试"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		Template t = null;
		try {
			//获取模板文件
			t = configuration.getTemplate("FMO-08 Packing List.ftl"); // 获取模板文件
		} catch (IOException e) {
			e.printStackTrace();
		}
		//生成一个文件保存的文件夹
		File file =new File("D:\\最终"); 
		//判断文件夹是否存在,存在删除并重创
		if  (!file .exists()  && !file .isDirectory())      
		{       
		    file.mkdir();    
		} else   
		{  
			boolean b = OperationIO.deleteDir(file);
			if(b){
				file.mkdir();
			}
		} 
		//填写数据后生成的word文件。
		String outfilepath = "D:/最终\\结果"+".doc";
		File outFile = new File(outfilepath); // 导出文件
		Writer out = null;
		try {
			try {
				out = new BufferedWriter(new OutputStreamWriter(
						new FileOutputStream(outFile),"utf-8"));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		try {
			t.process(paraMap,out); // 将填充数据填入模板文件并输出到目标文件
			out.flush();
			out.close();
			//转换PDF的文件
			OperationIO.wordToPDF(outfilepath,"D:/最终\\结果"+".pdf");
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

总结:通过以上代码,就可以在模板中填写好数据,并将其生成word文件与其pdf文件。你们有更好的方法也可以向博主介绍,我是个热爱学习的小白程序员。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值