java使用jacob实现word转pdf
作者:房产二公子 发布时间:2023-05-12 11:45:33
标签:java,jacob,word,pdf
背景:日常开发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.dll到jdk\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文件。
来源:https://blog.csdn.net/qq_31170429/article/details/78424973


猜你喜欢
- 一、项目介绍【知识准备】①Android Interface definition language(aidl,android接口定义语言)
- 本文实例讲述了C#多线程处理多个队列数据的方法。分享给大家供大家参考。具体实现方法如下:using System;using System.
- 作为Android应用开发者,不得不面对一个尴尬的局面,就是自己辛辛苦苦开发的应用可以被别人很轻易的就反编译出来。Google似乎也发现了这
- 前言上节在谈论Bean的实例化过程时,在说明实例化后阶段时只是粗略地看了一下populateBean,并未展开分析。本节接着populate
- C# 复制与删除文件的实现方法1、首先是复制文件首先打开我们的对话框获得文件路径,当然也可以直接编写路径private void BtnAd
- 前言本文重点是要将mongodb与spring整合到项目中去,在实践中发现问题,追踪问题,然后解决问题。下面话不多说了,来一起看看详细的介绍
- 常用命令:打包:mvn package编译:mvn compile清空:mvn clean(清除编译后目录,默认是target目录)运行测试
- 在做多语言版本的时候,日期时间的格式话是一个很头疼的事情,幸好Android提供了DateFormate,可以根据指定的语言区域的默认格式来
- 场景需要判断,首字母是否是英文字母。有人说,那还不简单么,StringUtils.isAlpha() 就可以搞定。 笔者也是这么想的,结果却
- VideoView介绍之前介绍过使用MediaPlayer+SurfaceView实现播放视频功能。无意间发现官方封装了VideoView组
- 本文以C#及VB.NET后端程序代码示例展示如何将HTML转为XML文件。转换时,调用Word API -Free Spire.Doc fo
- 前言 对于服务端,达到高性能、高扩展离不开异步。对于客户端,函数执行时间是1毫秒还是100毫秒
- 今天看到一个银行的APP上面的loadingview 挺好的,就尝试着自己实现,觉得很简单,但自己实现起来还是发现了一些问题。Loading
- feignclient https接口调用报证书错误问题最近在使用 feignclient 过程中,和第三方通过https 协议交互的时候,
- 一般有点开发经验的朋友都能实现这样的功能,只不过是效率上的问题。我们一般在面对这样的问题时,总会平铺直序的联想到,先生成一个数组,然后在一个
- Java Runnable线程传参,让run访问参数前言做Android开发,可能经常要用到Runnable线程,有时候可能需要传参数进去,
- 表单提交此处的表单时 -使用JSON.stringify()函数将数组转换成json类型提交后台,后台使用@RequestBody User
- 前言由于android M的popupwindow与之前版本不一致,笔者找不到能够代码监听物理返回键的方式,故另寻方式实现筛选菜单。5.0及
- 先贴正确配置<?xml version="1.0" encoding="UTF-8"?>
- 目录示例1: EncryptByAes示例2: main示例3: wrapperPublicPriviteKeyTest示例4: initH