项目中需要使用到office文件的预览服务,开发过程中使用[office365](http://www.officeweb365.com/)
作文件预览,但是实际生产环境为内网,所以只能使用自己的文件预览。后来发现网上的openoffice组件可以提供文件的在线预览。
1.在openoffice官网下载[windows安装包](http://www.openoffice.org/download/index.html)(也可以支持linux等,
我开发时选择的是windows)
下载后直接基本一直点下一步就可以,在中间需要记住安装的目录,会在开发中使用。安装好之后启动openoffice需要进入安装目录下的program中,按shift+鼠标右键选择打开windows命令行
执行: soffice -headless -accept=“socket,host=127.0.0.1,port=8100;urp;” -nofirststartwizard
查看是否启动成功:netstat -ano|findstr “8100”
2.下载swfttools,用于将pdf转换成swf文件,并安装。
3.下载pdf.js文件,用于前端展示转换成pdf的文件。
4.在项目中引入openoffice相关的jar
com.hand.hap
jodconverter
2.2.2
org.openoffice
juh
4.1.2
org.openoffice
jurt
4.1.2
org.openoffice
ridl
4.1.2
org.openoffice
unoil
4.1.2
com.thoughtworks.xstream
xstream
1.4.10
其中jodconverter2.2.2在仓库中没有,需要自己上传后引入。可以网上搜索后下载。
5.将pdf.js解压后引入项目中。我在项目中引入的路径为如下。
6.编写预览文件的页面,其实就是通过ifram引入pdf中的viewer.html。我的代码如下:
预览
7.后台controller代码:
package com.acat.controller.filepreview;
import com.acat.util.DocConverter;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Description:文件转换成pdf
* @Author:
* @Date: Created in 15:48 2019-04-18
* @Modified By:
*/
@RestController
@RequestMapping("/filePreview")
public class FilePreviewController {
/**
* 将文件转换成pdf并返回路径 produces = "text/plain;charset=utf-8"用于解决返回中文文件名乱码问题,如果spring中已经配置过就不需要
* @param fileUrl 文件的url
* @param fileLocation 文件地址
* @param request
* @param response
* @return 返回生成的pdf文件地址
*/
@ResponseBody
@PostMapping(value = "/onlinefile",produces = "text/plain;charset=utf-8")
public String onlinefile(@RequestParam(value = "fileUrl")String fileUrl,@RequestParam(value = "fileLocation")String fileLocation,HttpServletRequest request, HttpServletResponse response) {
String pdfFileLocation;
response.setHeader("Access-Control-Allow-Origin", "*");
String filePath = request.getSession().getServletContext().getRealPath("/");
//源文件地址调用的方法同样需要传文件的绝对路径
DocConverter d = new DocConverter(filePath+fileUrl);
//d.getPdfName()是返回的文件名 需要加上项目绝对路径 不然会以相对路径访问资源
d.conver();
pdfFileLocation = fileLocation+d.getPdfName();
return pdfFileLocation;
}
}
8.文件转换类的代码:(linux的代码后期逐步完善)
package com.acat.util;
import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.PdfWriter;
import org.apache.log4j.Logger;
/**
* @Description:openoffice将文件转换为pdf的工具类
* @Author:
* @Date: Created in 16:07 2019-04-18
* @Modified By:
*/
public class DocConverter {
private static final Logger logger = Logger.getLogger(DocConverter.class);
/**
* 环境 1:windows 2:linux
*/
private static final Integer WINDOWS_ENVIROMENT=1;
private static final Integer LINUX_ENVIROMENT=2;
private static final int environment = WINDOWS_ENVIROMENT;
/**
* (只涉及pdf2swf路径问题)
*/
private String fileString;
/**
* 输入路径 ,如果不设置就输出在默认的位置
*/
private String outputPath = "";
private String fileName;
/**
* office办公软件格式
*/
private static String[] docFileLayouts = { ".txt", ".doc", ".docx", ".wps", ".xls", ".xlsx", ".et", ".ppt", ".pptx",
".dps" };
/**
* 图片格式
*/
private static String[] imgFileLayouts = { ".jpg", ".gif", ".jpeg", ".png", ".bmp" };
/**
* pdf格式
*/
private static String[] pdfFileLayouts = { ".pdf" };
private File imgFile;
/**
* 原文件
*/
private File oldFile;
private File pdfFile;
private File swfFile;
private File docFile;
private String pdf2swfPath;
/**
* 可预览的文件格式
*
* @param
*/
public static String getPreviewFileExt() {
List list = new ArrayList(Arrays.asList(docFileLayouts));
list.addAll(Arrays.asList(imgFileLayouts));
list.addAll(Arrays.asList(pdfFileLayouts));
Object[] c = list.toArray();
return Arrays.toString(c);
}
public DocConverter(String fileurl) {
ini(fileurl);
}
/**
* 重新设置file
* @param fileurl
*/
public void setFile(String fileurl) {
ini(fileurl);
}
/**
* 初始化
* @param fileurl
*/
private void ini(String fileurl) {
this.fileString = fileurl;
fileName = fileString.substring(0, fileString.lastIndexOf("."));
int type = fileString.lastIndexOf(".");
String typeStr = fileString.substring(type);
if (Arrays.toString(docFileLayouts).contains(typeStr)) {
docFile = new File(fileString);
} else if (Arrays.toString(imgFileLayouts).contains(typeStr)) {
imgFile = new File(fileString);
} else if (Arrays.toString(pdfFileLayouts).contains(typeStr)) {
oldFile = new File(fileString);
}
pdfFile = new File(fileName + ".pdf");
}
/**
* 转为PDF
*/
private void doc2pdf() throws Exception {
if (docFile != null && docFile.exists()) {
if (!pdfFile.exists()) {
//openoffice的连接地址及端口
OpenOfficeConnection connection = new SocketOpenOfficeConnection("localhost", 8100);
try {
connection.connect();
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
converter.convert(docFile, pdfFile);
connection.disconnect();
logger.info("pdf转换成功,PDF输出地址为:" + pdfFile.getPath());
} catch (java.net.ConnectException e) {
e.printStackTrace();
logger.info("swf转换器异常,openoffice服务未启动!");
throw e;
} catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) {
e.printStackTrace();
logger.info("swf转换器异常,读取转换文件失败");
throw e;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
} else {
logger.info("已经转换为pdf,不需要再进行转化");
}
} else {
logger.info("swf转换器异常,需要转换的文档不存在,无法转换");
}
}
/**
* 将图片转换成pdf文件 imgFilePath 需要被转换的img所存放的位置。
* 例如imgFilePath="D:\\projectPath\\55555.jpg"; pdfFilePath 转换后的pdf所存放的位置
* 例如pdfFilePath="D:\\projectPath\\test.pdf";
* @return
* @throws IOException
* @throws Exception
*/
private void imgToPdf() throws Exception {
if (imgFile != null && imgFile.exists()) {
if (!pdfFile.exists()) {
Document document = new Document();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(pdfFile.getPath());
PdfWriter.getInstance(document, fos);
// 添加PDF文档的某些信息,比如作者,主题等等
document.addAuthor("神朔铁路机务段");
// document.addSubject("test pdf.");
// 设置文档的大小
document.setPageSize(PageSize.A4);
// 打开文档
document.open();
// 写入一段文字document.add(new Paragraph("JUST TEST ..."));
// 读取一个图片
Image image = Image.getInstance(imgFile.getPath());
float imageHeight = image.getScaledHeight();
float imageWidth = image.getScaledWidth();
int i = 0;
while (imageHeight > 500 || imageWidth > 500) {
image.scalePercent(100 - i);
i++;
imageHeight = image.getScaledHeight();
imageWidth = image.getScaledWidth();
}
image.setAlignment(Image.ALIGN_CENTER);
document.add(image);
} catch (Exception de) {
System.out.println(de.getMessage());
}
document.close();
fos.flush();
fos.close();
}
}
}
/**
* 转换成 pdf
*/
@SuppressWarnings("unused")
private void pdfTopdf() throws Exception {
Runtime r = Runtime.getRuntime();
if (!pdfFile.exists() && oldFile.exists()) {
// windows环境处理
if (environment == WINDOWS_ENVIROMENT) {
try {
int bytesum = 0;
int byteread = 0;
File oldfile = new File(oldFile.getPath());
// 文件存在时
if (oldfile.exists()) {
// 读入原文件
InputStream inStream = new FileInputStream(oldFile.getPath());
FileOutputStream fs = new FileOutputStream(pdfFile.getPath());
byte[] buffer = new byte[1444];
int length;
while ((byteread = inStream.read(buffer)) != -1) {
// 字节数 文件大小
bytesum += byteread;
fs.write(buffer, 0, byteread);
}
inStream.close();
}
} catch (Exception e) {
logger.info("复制单个文件操作出错");
e.printStackTrace();
}
// linux环境处理 TODO参照windows下进行操作
} else if (environment == LINUX_ENVIROMENT) {
}
} else {
logger.info("pdf不存在,无法转换");
}
}
/**
* 转换成 swf
*/
@SuppressWarnings("unused")
private void pdf2swf() throws Exception {
Runtime r = Runtime.getRuntime();
if (!swfFile.exists()) {
if (pdfFile.exists()) {
// windows环境处理
if (environment == WINDOWS_ENVIROMENT) {
try {
// 从配置文件获取swfFile.exe 安装路径
InputStream in = DocConverter.class.getClassLoader()
.getResourceAsStream("flow/pdf2swfPath.properties");
Properties config = new Properties();
try {
config.load(in);
in.close();
} catch (IOException e) {
System.err.println("加载配置文件失败");
}
if (config != null && config.getProperty("pdf2swfPath") != null) {
pdf2swfPath = config.getProperty("pdf2swfPath").toString();
}
Process p = r
.exec(pdf2swfPath + " " + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9");
swfFile = new File(swfFile.getPath());
} catch (IOException e) {
e.printStackTrace();
throw e;
}
// linux环境处理TODO参照windows下进行操作
} else if (environment == LINUX_ENVIROMENT) {
try {
Process p = r.exec("pdf2swf " + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9");
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
} else {
System.out.println("pdf不存在,无法转换");
}
} else {
System.out.println("swf已经存在不需要转换");
}
}
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();
}
/**
* 转换主方法
*/
@SuppressWarnings("unused")
public boolean conver() {
if (pdfFile.exists()) {
logger.info("swf转换器开始工作,该文件已经转换为swf");
return true;
}
if (environment == WINDOWS_ENVIROMENT) {
logger.info("swf转换器开始工作,当前设置运行环境windows");
} else {
logger.info("****swf转换器开始工作,当前设置运行环境linux");
}
try {
doc2pdf();
imgToPdf();
pdfTopdf();
} catch (Exception e) {
e.printStackTrace();
return false;
}
if (pdfFile.exists()) {
return true;
} else {
return false;
}
}
/**
* 返回文件路径
*/
public String getPdfName() {
String tempString = pdfFile.getName();
return tempString;
}
/**
* 设置输出路径
*/
public void setOutputPath(String outputPath) {
this.outputPath = outputPath;
if (!outputPath.equals("")) {
String realName = fileName.substring(fileName.lastIndexOf("/"), fileName.lastIndexOf("."));
if (outputPath.charAt(outputPath.length()) == '/') {
swfFile = new File(outputPath + realName + ".swf");
} else {
swfFile = new File(outputPath + realName + ".swf");
}
}
}
}
文件中有一个配置文件flow/pdf2swfPath.properties,用于配置pdf2swfPath的安装目录:
##pdf2swfPath的安装目录
pdf2swfPath=D:/openoffice/soft/swfttools/pdf2swf.exe
到这里文件转换就完成了,这里需要注意,进行转换时候,需要将openoffice开启。我尝试过txt,docx,pptx,xlsx文件均正常。
我将需要的相关jar及js上传到我的下载中,需要的可以去下载。