最近遇到一个需求,需要在手机前端直接查看office文档,在搜索前端解决方法无果后,开始寻找JAVA的解决方案。
一:windows 环境
一开始找到的是java的jacob,只适用于windows环境。代码如下:
注意点:1、windows环境下,需要配置path环境变量(注意重启,一定要重启。。捂脸)
我的是:C:\Program Files\LibreOffice 5\program
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.platform.cubism.util.CubismHelper;
public class Word2Pdf {
private final static Logger logger = LoggerFactory.getLogger(Word2Pdf.class);
private static String root = CubismHelper.getAppRootDir() + "files\\party\\";
private static String pdfroot = CubismHelper.getAppRootDir() + "files\\party\\pdf";
public static void main(String[] args) {
String filename ="C:\\Users\\Administrator\\Desktop\\temp.docx";
String newname = String.valueOf(System.nanoTime()) + filename.substring(filename.lastIndexOf('.'));
int dot = newname.lastIndexOf('.');
String suffix = "";
if ((dot >-1) && (dot < (newname.length()))) {
suffix = newname.substring(dot + 1).toUpperCase();
}
//这里注释掉的是我上传文件所走的方法。
// MultipartUtils.saveStreamToFile(part.getInputStream(), root + newname, -1L);
if(suffix.equals("DOCX")|| suffix=="DOCX" || suffix.equals("DOC") || suffix=="DOC"){
String pdfname = newname.substring(0, dot)+".pdf";
wordtopdf(root + newname, pdfroot + pdfname);
}
}
public static Boolean wordtopdf(String filepath,String pdfpath){
ActiveXComponent app = null;
String wordFile =filepath;// filepath;
String pdfFile = pdfpath;//pdfpath;
logger.debug("word文档路径"+filepath);
logger.debug("pdf文档路径"+pdfpath);
// 开始时间
long start = System.currentTimeMillis();
try {
// 打开word
app = new ActiveXComponent("Word.Application");
// 获得word中所有打开的文档
Dispatch documents = app.getProperty("Documents").toDispatch();
logger.debug("打开文件"+wordFile);
// 打开文档
Dispatch document = Dispatch.invoke(
documents,
"Open",
Dispatch.Method,
new Object[] { wordFile, new Variant(false),
new Variant(true) }, new int[1]).toDispatch();
// 如果文件存在的话,不会覆盖,会直接报错,所以我们需要判断文件是否存在
File target = new File(pdfFile);
File fileParent = target.getParentFile();
//如果文件夹不存在则创建
if (!fileParent.exists() && !fileParent .isDirectory())
{
logger.debug(pdfpath+"文件夹不存在,创建");
fileParent.mkdir();
}
//如果该文件本身存在,会报错,所以在这里进行判断。
if(target.exists())
{
target.delete();
}
logger.debug("另存为"+pdfFile);
// 另存为,将文档报错为pdf,其中word保存为pdf的格式宏的值是17
Dispatch.invoke(document,
"SaveAs",
Dispatch.Method,
new Object[] {pdfFile,new Variant(17)},
new int[1]);
// 关闭文档
Dispatch.call(document, "Close", false);
// 结束时间
long end = System.currentTimeMillis();
logger.debug("转换成功,用时:" + (end - start) + "ms");
return true;
} catch (Exception e) {
logger.error("转换失败"+e.getMessage());
}finally{
// 关闭office
app.invoke("Quit", 0);
}
return false;
}
}
maven 引用
net.sf.jacob-project
jacob
1.14.3
二.windows 环境测试 +linux 环境部署
因jacob无法运行于linux环境,因此找到了libreOffice。代码如下:
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LibreOffice {
private final static Logger logger = LoggerFactory.getLogger(LibreOffice.class);
public static boolean wordConverterToPdf(String filepath,String pdfpath) throws Exception {
File file = new File(filepath);
String path = pdfpath;
logger.debug("filepath++++++++++++++++++++++"+filepath);
logger.debug("path++++++++++++++++++++++"+path);
try {
String osName = System.getProperty("os.name");
String command = "";
if (osName.contains("Windows")) {
command = "soffice --convert-to pdf -outdir " + path +" "+ filepath;
logger.debug("command1++++++++++++++++++++++"+command);
} else {
command = "doc2pdf --output=" + path + File.separator + file.getName().replaceAll(".(?i)docx", ".pdf") + " " + filepath;
logger.debug("command2++++++++++++++++++++++"+command);
}
String result = CommandExecute.executeCommand(command);
if (result.equals("") || result.contains("writer_pdf_Export")) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return false;
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 命令行执行
* @author Administrator
* @date: 日期:2018-3-28 时间:下午4:26:10
*/
public class CommandExecute {
private final static Logger logger = LoggerFactory.getLogger(CommandExecute.class);
public static String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
int data =0;
InputStreamReader inputStreamReader = null;
BufferedReader reader = null;
try {
logger.debug(command);
p = Runtime.getRuntime().exec(command);
p.waitFor();
inputStreamReader = new InputStreamReader(p.getInputStream(), "UTF-8");
reader = new BufferedReader(inputStreamReader);
while((data = inputStreamReader.read())!=-1){
System.out.println((byte)data);
}
InputStream isErr = p.getErrorStream();
data =0;
while((data = isErr.read())!=-1){
System.out.println((byte)data);
}
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(inputStreamReader);
}
logger.debug(output.toString());
return output.toString();
}
}
感谢@李建国(Jianguo Li) 的博客,他的GitHub https://github.com/AryaRicky/toPdfUtils