先說(shuō)一說(shuō)如何實(shí)現(xiàn)在線預(yù)覽doc
網(wǎng)上查了很多資料,基本思路就是將 doc 轉(zhuǎn)為 pdf,由于低版本瀏覽器不支持預(yù)覽 pdf,所以基本是再將 pdf 轉(zhuǎn)為 swf (使用FlexPaper + swftools)
本文使用 pdf.js + jodconverter + openOffice
Java 如何將doc 轉(zhuǎn)為 pdf?
- poi讀取doc + itext生成pdf (實(shí)現(xiàn)最方便,效果最差,跨平臺(tái))
- jodconverter + openOffice (一般格式實(shí)現(xiàn)效果還行,復(fù)雜格式容易有錯(cuò)位,跨平臺(tái))
- jacob + msOfficeWord + SaveAsPDFandXPS (完美保持原doc格式,效率最慢,只能在windows環(huán)境下進(jìn)行)
準(zhǔn)備工作
(正式環(huán)境部署安裝的是libreoffice,openopenOffice的衍生版,之前有些無(wú)法轉(zhuǎn)換的doc文件,使用libreoffice后正常轉(zhuǎn)換)
linux上環(huán)境所需要的字體包 和 libreoffice https://pan.baidu.com/s/1mjhpdna 密碼: 82ca
- 安裝后,使用以下命令可以啟動(dòng)openoffice
soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard - windows下查看是否啟動(dòng)
netstat -ano|findstr "8100"

Talk is cheap. Show me the code
jodconverter 所需 maven依賴(lài)
<!-- jodconverter-->
<dependency>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter</artifactId>
<version>2.2.1</version>
</dependency>
文件轉(zhuǎn)換核心類(lèi)
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格式轉(zhuǎn)換
*/
public class DocConverter {
private static final int environment = 1;// 環(huán)境 1:windows 2:linux
private String fileString;// (只涉及pdf2swf路徑問(wèn)題)
private String outputPath = "";// 輸入路徑 ,如果不設(shè)置就輸出在默認(rèn)的位置
private String fileName;
private File pdfFile;
private File swfFile;
private File docFile;
public DocConverter(String fileString) {
ini(fileString);
}
/**
* 重新設(shè)置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");
}
/**
* 轉(zhuǎn)為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轉(zhuǎn)換成功,PDF輸出:" + pdfFile.getPath()+ "****");
} catch (java.net.ConnectException e) {
e.printStackTrace();
System.out.println("****swf轉(zhuǎn)換器異常,openoffice服務(wù)未啟動(dòng)!****");
throw e;
} catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) {
e.printStackTrace();
System.out.println("****swf轉(zhuǎn)換器異常,讀取轉(zhuǎn)換文件失敗****");
throw e;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
} else {
System.out.println("****已經(jīng)轉(zhuǎn)換為pdf,不需要再進(jìn)行轉(zhuǎn)化****");
}
} else {
System.out.println("****swf轉(zhuǎn)換器異常,需要轉(zhuǎn)換的文檔不存在,無(wú)法轉(zhuǎn)換****");
}
}
/**
* 轉(zhuǎn)換成 swf
*/
@SuppressWarnings("unused")
private void pdf2swf() throws Exception {
Runtime r = Runtime.getRuntime();
if (!swfFile.exists()) {
if (pdfFile.exists()) {
if (environment == 1) {// windows環(huán)境處理
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轉(zhuǎn)換成功,文件輸出:"
+ swfFile.getPath() + "****");
if (pdfFile.exists()) {
pdfFile.delete();
}
} catch (IOException e) {
e.printStackTrace();
throw e;
}
} else if (environment == 2) {// linux環(huán)境處理
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轉(zhuǎn)換成功,文件輸出:"
+ swfFile.getPath() + "****");
if (pdfFile.exists()) {
pdfFile.delete();
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
} else {
System.out.println("****pdf不存在,無(wú)法轉(zhuǎn)換****");
}
} else {
System.out.println("****swf已經(jīng)存在不需要轉(zhuǎn)換****");
}
}
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();
}
/**
* 轉(zhuǎn)換主方法
*/
@SuppressWarnings("unused")
public boolean conver() {
if (swfFile.exists()) {
System.out.println("****swf轉(zhuǎn)換器開(kāi)始工作,該文件已經(jīng)轉(zhuǎn)換為swf****");
return true;
}
if (environment == 1) {
System.out.println("****swf轉(zhuǎn)換器開(kāi)始工作,當(dāng)前設(shè)置運(yùn)行環(huán)境windows****");
} else {
System.out.println("****swf轉(zhuǎn)換器開(kāi)始工作,當(dāng)前設(shè)置運(yùn)行環(huán)境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 "";
}
}
/**
* 設(shè)置輸出路徑
*/
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
百度網(wǎng)盤(pán): https://pan.baidu.com/s/1dHk0IQH 密碼: n47x
將 generic 文件夾復(fù)制到項(xiàng)目中即可
我使用的是springboot工程,添加靜態(tài)資源訪問(wèn)(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;
}
}
請(qǐng)求 http://localhost:8080/pdf/web/viewer.html?file=/displayPDF/4 會(huì)跳轉(zhuǎn)到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;
/**
* 文件預(yù)覽
*
* @author @Taven
*
*/
@Controller
public class FilePreview {
@RequestMapping("/displayPDF/{id}")
public void displayPDF(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) {
//xxx 邏輯
// 調(diào)用轉(zhuǎn)換類(lèi)
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實(shí)現(xiàn)附件預(yù)覽(openoffice+swftools+flexpaper)
java集成pdf.js實(shí)現(xiàn)pdf文件在線預(yù)覽