java 在线预览doc,pdf
2018-01-18 本文已影响2043人
殷天文
先说一说如何实现在线预览doc
网上查了很多资料,基本思路就是将 doc 转为 pdf,由于低版本浏览器不支持预览 pdf,所以基本是再将 pdf 转为 swf (使用FlexPaper + swftools)
本文使用 pdf.js + jodconverter + openOffice
Java 如何将doc 转为 pdf?
- poi读取doc + itext生成pdf (实现最方便,效果最差,跨平台)
- jodconverter + openOffice (一般格式实现效果还行,复杂格式容易有错位,跨平台)
- jacob + msOfficeWord + SaveAsPDFandXPS (完美保持原doc格式,效率最慢,只能在windows环境下进行)
准备工作
(正式环境部署安装的是libreoffice,openopenOffice的衍生版,之前有些无法转换的doc文件,使用libreoffice后正常转换)
linux上环境所需要的字体包 和 libreoffice https://pan.baidu.com/s/1mjhpdna 密码: 82ca
- 安装后,使用以下命令可以启动openoffice
soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard
- windows下查看是否启动
netstat -ano|findstr "8100"
Talk is cheap. Show me the code
jodconverter 所需 maven依赖
<!-- jodconverter-->
<dependency>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter</artifactId>
<version>2.2.1</version>
</dependency>
文件转换核心类
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
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;
/**
* doc docx格式转换
*/
public class DocConverter {
private static final int environment = 1;// 环境 1:windows 2:linux
private String fileString;// (只涉及pdf2swf路径问题)
private String outputPath = "";// 输入路径 ,如果不设置就输出在默认的位置
private String fileName;
private File pdfFile;
private File swfFile;
private File docFile;
public DocConverter(String fileString) {
ini(fileString);
}
/**
* 重新设置file
*
* @param fileString
*/
public void setFile(String fileString) {
ini(fileString);
}
/**
* 初始化
*
* @param fileString
*/
private void ini(String fileString) {
this.fileString = fileString;
fileName = fileString.substring(0, fileString.lastIndexOf("."));
docFile = new File(fileString);
pdfFile = new File(fileName + ".pdf");
swfFile = new File(fileName + ".swf");
}
/**
* 转为PDF
*
* @param file
*/
private void doc2pdf() throws Exception {
if (docFile.exists()) {
if (!pdfFile.exists()) {
OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
try {
connection.connect();
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
converter.convert(docFile, pdfFile);
// close the connection
connection.disconnect();
System.out.println("****pdf转换成功,PDF输出:" + pdfFile.getPath()+ "****");
} catch (java.net.ConnectException e) {
e.printStackTrace();
System.out.println("****swf转换器异常,openoffice服务未启动!****");
throw e;
} catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) {
e.printStackTrace();
System.out.println("****swf转换器异常,读取转换文件失败****");
throw e;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
} else {
System.out.println("****已经转换为pdf,不需要再进行转化****");
}
} else {
System.out.println("****swf转换器异常,需要转换的文档不存在,无法转换****");
}
}
/**
* 转换成 swf
*/
@SuppressWarnings("unused")
private void pdf2swf() throws Exception {
Runtime r = Runtime.getRuntime();
if (!swfFile.exists()) {
if (pdfFile.exists()) {
if (environment == 1) {// windows环境处理
try {
Process p = r.exec("D:/Program Files/SWFTools/pdf2swf.exe "+ pdfFile.getPath() + " -o "+ swfFile.getPath() + " -T 9");
System.out.print(loadStream(p.getInputStream()));
System.err.print(loadStream(p.getErrorStream()));
System.out.print(loadStream(p.getInputStream()));
System.err.println("****swf转换成功,文件输出:"
+ swfFile.getPath() + "****");
if (pdfFile.exists()) {
pdfFile.delete();
}
} catch (IOException e) {
e.printStackTrace();
throw e;
}
} else if (environment == 2) {// linux环境处理
try {
Process p = r.exec("pdf2swf " + pdfFile.getPath()
+ " -o " + swfFile.getPath() + " -T 9");
System.out.print(loadStream(p.getInputStream()));
System.err.print(loadStream(p.getErrorStream()));
System.err.println("****swf转换成功,文件输出:"
+ swfFile.getPath() + "****");
if (pdfFile.exists()) {
pdfFile.delete();
}
} 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 (swfFile.exists()) {
System.out.println("****swf转换器开始工作,该文件已经转换为swf****");
return true;
}
if (environment == 1) {
System.out.println("****swf转换器开始工作,当前设置运行环境windows****");
} else {
System.out.println("****swf转换器开始工作,当前设置运行环境linux****");
}
try {
doc2pdf();
pdf2swf();
} catch (Exception e) {
e.printStackTrace();
return false;
}
if (swfFile.exists()) {
return true;
} else {
return false;
}
}
/**
* 返回文件路径
*
* @param s
*/
public String getswfPath() {
if (swfFile.exists()) {
String tempString = swfFile.getPath();
tempString = tempString.replaceAll("\\\\", "/");
return tempString;
} else {
return "";
}
}
/**
* 设置输出路径
*/
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");
}
}
}
}
使用PDF.js
百度网盘: https://pan.baidu.com/s/1dHk0IQH 密码: n47x
将 generic 文件夹复制到项目中即可
我使用的是springboot工程,添加静态资源访问(generic 我重命名为 pdf)
@Configuration
@ComponentScan
public class TXAppConfigurer extends WebMvcConfigurerAdapter implements ApplicationContextAware {
private ApplicationContext applicationContext;
public TXAppConfigurer() {
super();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pdf/**")
.addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/pdf/");
super.addResourceHandlers(registry);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
请求 http://localhost:8080/pdf/web/viewer.html?file=/displayPDF/4 会跳转到controller
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.txgl.util.DocConverter;
/**
* 文件预览
*
* @author @Taven
*
*/
@Controller
public class FilePreview {
@RequestMapping("/displayPDF/{id}")
public void displayPDF(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) {
//xxx 逻辑
// 调用转换类
DocConverter docConverter = new DocConverter("your filePath");
try {
docConverter.doc2pdf();
File pdf = docConverter.getPdf();
FileInputStream fileInputStream = new FileInputStream(pdf);
response.reset();
response.setHeader("Content-Disposition", "attachment;fileName=test.pdf");
response.setContentType("multipart/form-data");
OutputStream outputStream = response.getOutputStream();
IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
}
参考博客:
java实现附件预览(openoffice+swftools+flexpaper)
java集成pdf.js实现pdf文件在线预览