环境准备
1、Office(wps无法转换)
2、window服务
3、pom依赖
<!-- PDF-jacob -->
<dependency>
<groupId>net.sf.jacob-project</groupId>
<artifactId>jacob</artifactId>
<version>1.14.3</version>
</dependency>
<!-- PDF-ITEXT -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.3.4</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
4、2个配置文件
jacob-1.14.3-x64.dll(对应jacob依赖版本)
放置于jdk对应bin目录下:
msyh.ttf (写水印的字体)
放置于对应目录下(因为将文件放置于项目中resource下,在打包时会把该文件编 译,会造成文件损坏,所以我这边用的是绝对路径)
配置文件链接: https://pan.baidu.com/s/1MeUHMzexEScDvwSqGQa3pQ 提取码: qwer
具体转换代码
PDFHelper
import cn.hutool.core.io.FileUtil;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.URL;
//import com.joinfun.utils.helper.FileHelper;
public class PDFHelper {
private static Logger logger = LoggerFactory.getLogger(PDFHelper.class);
//private static String OWNER_PASS = "HLPass1234";
private static String USER_PASS = "HLPass1234";
private static final int wordFormatPDF = 17;// WORD转PDF格式
private static final int pptSaveAsPDF = 32;// PPT转PDF格式
private static final int wdDoNotSaveChanges = 0;// 不保存待定的更改
/**
* WORD转PDF
*
* @param source
* @param target
* @throws Exception
*/
public static void word2pdf(String source, String target) throws Exception {
ComThread.InitSTA();// 初始化com的线程
ActiveXComponent app = null;
try {
logger.info("运行WORD");
app = new ActiveXComponent("Word.Application");
app.setProperty("Visible", false);
Dispatch docs = app.getProperty("Documents").toDispatch();
logger.info("打开WORD文件:" + source);
Dispatch doc = Dispatch.call(docs, "Open", source, false,// ConfirmConversions
true // ReadOnly
).toDispatch();
logger.info("删除旧的目标文件:" + target);
deleteOldFile(target);
logger.info("SAVE AS方式转换PDF文件:" + target);
Dispatch.call(doc, "SaveAs", target, wordFormatPDF);
logger.info("CLOSE");
Dispatch.call(doc, "Close", false);
} catch (Exception e) {
logger.error("WORD-PDF转换失败:" + e.getMessage());
throw e;
} finally {
if (app != null) {
app.invoke("Quit", wdDoNotSaveChanges);
}
ComThread.Release();// 释放com的线程
}
}
private static void deleteOldFile(String target) {
File tofile = new File(target);
if (tofile.exists()) {
tofile.delete();
}
}
private static void deleteOldFile(String target , int page) {
for(int i = 1 ; i <= page; i++){
File tofile = new File(target + i + ".swf");
if (tofile.exists()) {
tofile.delete();
}
}
}
public static int getPdfPageCount(File file) throws IOException{
PdfReader reader = null;
FileInputStream fs = null;
try{
fs = new FileInputStream(file);
reader = new PdfReader(fs);
int pageCount = reader.getNumberOfPages();
return pageCount;
} catch(Exception e1){
return 0;
} finally{
if(reader != null){
reader.close();
}
if(fs != null){
fs.close();
}
}
}
public static void xls2pdf(String source, String target) throws Exception {
ComThread.InitSTA();// 初始化com的线程
ActiveXComponent app = null;
try {
logger.info("运行EXCEL");
app = new ActiveXComponent("Excel.Application");
app.setProperty("Visible", new Variant(false));
Dispatch workbooks = app.getProperty("Workbooks").toDispatch();
logger.info("打开EXCEL文件:" + source);
Dispatch workbook = Dispatch.invoke(
workbooks,
"Open",
Dispatch.Method,
new Object[]{source, new Variant(false),
new Variant(true)}, new int[1]).toDispatch();
logger.info("删除旧的目标文件:" + target);
deleteOldFile(target);
logger.info("SAVE AS方式转换PDF文件:" + target);
Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[]{
target, new Variant(57), new Variant(false),
new Variant(57), new Variant(57), new Variant(false),
new Variant(true), new Variant(57), new Variant(true),
new Variant(true), new Variant(true)}, new int[1]);
logger.info("CLOSE");
Dispatch.call(workbook, "Close", false);
} catch (Exception e) {
logger.error("EXCEL-PDF转换失败:" + e.getMessage());
throw e;
} finally {
if (app != null) {
app.invoke("Quit", new Variant[]{});
}
ComThread.Release();// 释放com的线程
}
}
public static void ppt2pdf(String source, String target) throws Exception {
ComThread.InitSTA();// 初始化com的线程
ActiveXComponent app = null;
try {
app = new ActiveXComponent("Powerpoint.Application");
Dispatch presentations = app.getProperty("Presentations")
.toDispatch();
logger.info("打开PPT文件:" + source);
Dispatch presentation = Dispatch.call(presentations, "Open",
source, true,// ReadOnly
true,// Untitled 指定文件是否有标题。
false // WithWindow 指定文件是否可见。
).toDispatch();
logger.info("删除旧的目标文件:" + target);
deleteOldFile(target);
logger.info("SAVE AS方式转换PDF文件:" + target);
Dispatch.call(presentation, "SaveAs", target, pptSaveAsPDF);
logger.info("CLOSE");
Dispatch.call(presentation, "Close");
} catch (Exception e) {
logger.error("PPT-PDF转换失败:" + e.getMessage());
throw e;
} finally {
if (app != null) {
app.invoke("Quit");
}
ComThread.Release();// 释放com的线程
}
}
public static void pdf2swf(String source, String target, boolean isFocusBitmap) throws Exception {
File sourceFile = new File(source);
if(!sourceFile.exists()){
throw new Exception("源文件不存在:" + source);
}
deleteOldFile(target); //删除旧的目标文件
int pageCount = getPdfPageCount(sourceFile); //PDF 页数
// long fileSize = FileHelper.getFileSize(sourceFile); //PDF 文件大小
long fileSize = FileUtil.size(sourceFile); //PDF 文件大小
Process process = null;
try{
source = "\"" + source + "\"";
target = "\"" + target + "\"";
if(isFocusBitmap){
System.out.println("使用BITMAP方式转化");
process = Runtime.getRuntime().exec("C:/SWFTools/pdf2swf.exe " + source + " -o " + target + " -T 9 -s bitmap -s languagedir=C:\\xpdf\\chinese");
} else {
if(pageCount < 15 && fileSize < 5171018){
System.out.println("使用普通方式转化");
process = Runtime.getRuntime().exec("C:/SWFTools/pdf2swf.exe " + source + " -o " + target + " -T 9 -s languagedir=C:\\xpdf\\chinese");
} else if (pageCount < 1000 && fileSize < 22138904l){
System.out.println("使用POLY2BITMAP方式转化");
process = Runtime.getRuntime().exec("C:/SWFTools/pdf2swf.exe " + source + " -o " + target + " -T 9 -s poly2bitmap -s languagedir=C:\\xpdf\\chinese");
} else {
System.out.println("使用BITMAP方式转化");
process = Runtime.getRuntime().exec("C:/SWFTools/pdf2swf.exe " + source + " -o " + target + " -T 9 -s bitmap -s languagedir=C:\\xpdf\\chinese");
}
}
StreamGobbler sg1 = new StreamGobbler(process.getInputStream(), "Console");
StreamGobbler sg2 = new StreamGobbler(process.getErrorStream(), "Error");
sg1.start();
sg2.start();
int result = process.waitFor();
if (result == 0){
// try {
// process.destroy();
// } catch (Exception e) {
// e.printStackTrace();
// }
}
} finally {
if(process != null){
try {
process.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static int pdf2swf(String source, String target) throws Exception {
File sourceFile = new File(source);
if(!sourceFile.exists()){
throw new Exception("源文件不存在:" + source);
}
int pageCount = getPdfPageCount(sourceFile); //PDF 页数
deleteOldFile(target, pageCount); //删除旧的目标文件
Process process = null;
try{
source = "\"" + source + "\"";
target = "\"" + target + "%.swf" + "\"";
process = Runtime.getRuntime().exec("C:/SWFTools/pdf2swf.exe " + source + " -o " + target + " -T 9 -s languagedir=C:\\xpdf\\chinese");
StreamGobbler sg1 = new StreamGobbler(process.getInputStream(), "Console");
StreamGobbler sg2 = new StreamGobbler(process.getErrorStream(), "Error");
sg1.start();
sg2.start();
process.waitFor();
} finally {
if(process != null){
try {
process.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return pageCount;
}
@SuppressWarnings("unused")
private static String loadStream(InputStream in) throws IOException {
int ptr = 0;
in = new BufferedInputStream(in);
StringBuffer buffer = new StringBuffer();
while ((ptr = in.read()) != -1) {
buffer.append((char) ptr);
}
return buffer.toString();
}
public static void notAllowPrint(String inputFile, String outFile) throws Exception {
PdfReader reader = new PdfReader(inputFile);
notAllowPrint(reader, outFile);
}
public static void notAllowPrint(InputStream inputStream, String outFile) throws Exception {
PdfReader reader = new PdfReader(inputStream);
notAllowPrint(reader, outFile);
}
public static void notAllowPrint(PdfReader reader, String outFile) throws Exception {
PdfEncryptor.encrypt(reader,
new FileOutputStream(outFile),
null,
USER_PASS.getBytes(),
PdfWriter.ALLOW_ASSEMBLY | PdfWriter.ALLOW_FILL_IN | PdfWriter.ALLOW_SCREENREADERS,
false);
}
public static void waterMarkByImg(String inputFile, String outputFile, String confidentialLevelId) throws Exception {
PdfReader reader = new PdfReader(inputFile);
FileOutputStream outputStream = new FileOutputStream(outputFile);
PdfStamper stamper = new PdfStamper(reader, outputStream);
URL url = PDFHelper.class.getResource("/dcc-water-mark-img/Confidential_" + confidentialLevelId + ".gif");
if (url == null) {
url = PDFHelper.class.getClassLoader().getResource("/dcc-water-mark-img/Confidential_" + confidentialLevelId + ".gif");
}
Image image = Image.getInstance(url.getPath());
image.setRotationDegrees(40);
image.scalePercent(100);
float imgWidth = image.getWidth();
float imgHeight = image.getHeight();
int total = reader.getNumberOfPages() + 1;
float pageWidth = 0;
float pageHeight = 0;
PdfContentByte under;
for (int i = 1; i < total; i++) {
pageWidth = reader.getPageSize(i).getWidth();
pageHeight = reader.getPageSize(i).getHeight();
under = stamper.getOverContent(i);
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.3f);// 设置透明度为0.2
under.setGState(gs);
image.setAbsolutePosition(pageWidth/2 - imgWidth/2, pageHeight/2 - imgHeight/2 - 40 * 2);
under.addImage(image);
}
stamper.close();
}
public static void waterMark(String inputFile, String outputFile, String waterMarkName) throws Exception {
PdfReader reader = new PdfReader(inputFile);
FileOutputStream outputStream = new FileOutputStream(outputFile);
PdfStamper pdfStamper = new PdfStamper(reader, outputStream);
PdfContentByte content = null;
Rectangle pageRect = null;
PdfGState gs = new PdfGState();
// 设置字体
//BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
// URL url = PDFHelper.class.getResource("/msyh.ttf");
// URL url = PDFHelper.class.getClassLoader().getResource("msyh.ttf");
String ttfPath="D://app/attach/msyh.ttf";
BaseFont base = BaseFont.createFont(ttfPath,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
if (base == null || pdfStamper == null) { return; }
// 设置透明度为0.4
gs.setFillOpacity(0.2f);
gs.setStrokeOpacity(0.2f);
int toPage = pdfStamper.getReader().getNumberOfPages();
for (int i = 1; i <= toPage; i++) {
pageRect = pdfStamper.getReader().getPageSizeWithRotation(i);
// 计算水印X,Y坐标
float x = pageRect.getWidth() / 2;
float y = pageRect.getHeight() / 2;
// 获得PDF最顶层
content = pdfStamper.getOverContent(i);
content.saveState();
// set Transparency
content.setGState(gs);
content.beginText();
content.setColorFill(BaseColor.GRAY);
content.setFontAndSize(base, 60);
// 水印文字成45度角倾斜
content.showTextAligned(Element.ALIGN_CENTER, waterMarkName, x, y, 45);
content.endText();
}
pdfStamper.close();
outputStream.close();
reader.close();
}
public static void waterMark4contract(String inputFile, String outputFile, String waterMarkName) throws Exception {
PdfReader reader = new PdfReader(inputFile);
FileOutputStream outputStream = new FileOutputStream(outputFile);
PdfStamper pdfStamper = new PdfStamper(reader, outputStream);
PdfContentByte content = null;
Rectangle pageRect = null;
PdfGState gs = new PdfGState();
// 设置字体
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
//BaseFont base = BaseFont.createFont("/msyh.ttf",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
if (base == null || pdfStamper == null) { return; }
// 设置透明度为0.4
gs.setFillOpacity(0.3f);
gs.setStrokeOpacity(0.3f);
int toPage = pdfStamper.getReader().getNumberOfPages();
for (int i = 1; i <= toPage; i++) {
pageRect = pdfStamper.getReader().getPageSizeWithRotation(i);
// 计算水印X,Y坐标
float x = pageRect.getWidth() / 2;
float y = pageRect.getHeight() / 2;
// 获得PDF最顶层
content = pdfStamper.getOverContent(i);
content.saveState();
// set Transparency
content.setGState(gs);
content.beginText();
content.setColorFill(BaseColor.GRAY);
float fontSize = 60;
if(waterMarkName.length() > 10){
fontSize = fontSize - (waterMarkName.length() / 5 * 4);
}
fontSize = fontSize - ((waterMarkName.getBytes("UTF-8").length - waterMarkName.length()) / 7 * 1);
content.setFontAndSize(base, fontSize);
// 水印文字成45度角倾斜
content.showTextAligned(Element.ALIGN_CENTER, waterMarkName, x, y, -45);
content.endText();
}
pdfStamper.close();
}
public static void main(String[] args){
// try {
try {
// PDFHelper.word2pdf("D://root/word.docx", "D://root/word.pdf");
// PDFHelper.xls2pdf("D://root/test.xlsx", "D://root/excel.pdf");
} catch (Exception e) {
e.printStackTrace();
}
// PDFHelper.ppt2pdf("d:/test/ppt.pptx", "d:/test/ppt.pdf");
// PDFHelper.pdf2swf("d:/test/word.pdf", "d:/test/word.swf");
// } catch (Exception e) {
// e.printStackTrace();
// }
try {
//waterMarkByImg("d:/1.pdf", "d:/2.pdf", "52");
waterMark4contract("c:/1.pdf", "c:/2.pdf", "上海宏利宏利斯蒂芬李经理阿萨德房间里艾丝凡");
} catch (Exception e) {
e.printStackTrace();
}
}
}
StreamGobbler
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class StreamGobbler extends Thread {
InputStream is;
String type;
private Log log = LogFactory.getLog("[SG]");
private static int i = 1;
private static int j = 1;
StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
i++;
j++;
String line = null;
while ((line = br.readLine()) != null) {
if (type.equals("Error")) {
log.error(line);
}else{
log.info(line);
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
调用
//sourceFile 可以是xlsx、xls、doc、docx、ppt、pptx
File sourceFile = FileUtil.file("D://root/test.xlsx");
File targetFile = FileUtil.file("D://root/test.pdf");
//根据具体转换调用具体的转换方法,例如:
PDFHelper.xls2pdf(sourceFile.getAbsolutePath(), targetFile.getAbsolutePath());