最近项目有这个需求,查找了一些资料,在这整理一下。
首先,pdf的文件,浏览器本身支持预览,不需要做什么处理。
controller:
简单说下思路:就是利用io流,将上传到文件服务器或保存到数据库的pdf文件,转成InputStream(FileInputStream亦可),输出流,获取 response.getOutputStream();
@RequestMapping("/devDoc")
InputStream input=null;
OutputStream out=null;
input=new ByteArrayInputStream(a);
response.setContentType("application/pdf");
out = response.getOutputStream();
byte[] b = new byte[512];
if(out!=null) {
if(input!=null) {
while ((input.read(b))!=-1) {
out.write(b);
}
}else {
System.out.println("InputStream为空。。。");
}
}else {
System.out.println("OutputStream为空。。。");
}
out.flush();
input.close();
out.close();
jsp:调用即可
//查看
function view(id){
window.open("<%=basePath%>Laws/devDoc.do?id="+id,"_blank","top=100,left=100,height=600,width=1000,status=yes,toolbar=1,menubar=no,location=no,scrollbas=yes");
}
接下来,说重点,实现word的在线预览,我想的一开始是将word转化为pdf,然后就可以预览了,找了一些资料,后来发现不行,不适用我这个项目(其实是我这外包公司,限制太多,不给装openOffice服务,我们也没有文件服务器,坑爹的存到数据库了,根本没有文件路径,我们是直接将文件流存到数据库了)
好了,说我是怎么做的把,选定了用poi来做,但是网上都说poi对word的支持很差,碰到宋体可能会变框框,一些表格之类的也会有问题,这些先不管了,就说用poi来做怎么做把。
poi 将word转化为html来展示
1.引jar
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<!-- 引入poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>xdocreport</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.3</version>
</dependency>
注意:poi的jar包版本至少的是3.15的,低于3.15的不支持docx的,就是不支持2007版,新版的word,只能支持doc,2003版的,这个版本也是,害的我折腾半天,还有就是,你要注意,你的项目,你要是子项目,注意看之前有没有引过poi,可能以前引的低版本的,你这个会识别不到(看主项目的build path里面,maven里边你引的poi是3.15)。
package com.htjc.longshine.Util;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.xwpf.converter.core.FileImageExtractor;
import org.apache.poi.xwpf.converter.core.FileURIResolver;
import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.w3c.dom.Document;
public class Doc2Html {
private final static String tempPath = "c:/test/";
/**
* doc转换为html
*
* @param
fileName
docx文件路径(如果你的是存到文件服务器的,直接用路径,如果是直接将文件流存到数据库的,转为InputStream )
* @param
outPutFile
html输出文件路径
* @throws TransformerException
* @throws IOException
* @throws ParserConfigurationException
*/
public static void doc2Html(InputStream fileName, String outPutFile) throws TransformerException, IOException, ParserConfigurationException {
long startTime = System.currentTimeMillis();
HWPFDocument wordDocument = new HWPFDocument(fileName);
//HWPFDocument wordDocument = new HWPFDocument(new FileInputStream(fileName));
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
wordToHtmlConverter.setPicturesManager(new PicturesManager() {
public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float widthInches, float heightInches) {
return "test/" + suggestedName;
}
});
wordToHtmlConverter.processDocument(wordDocument);
// 保存图片
List<Picture> pics = wordDocument.getPicturesTable().getAllPictures();
if (pics != null) {
for (int i = 0; i < pics.size(); i++) {
Picture pic = (Picture) pics.get(i);
System.out.println();
try {
pic.writeImageContent(new FileOutputStream(tempPath + pic.suggestFullFileName()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Document htmlDocument = wordToHtmlConverter.getDocument();
ByteArrayOutputStream out = new ByteArrayOutputStream();
DOMSource domSource = new DOMSource(htmlDocument);
StreamResult streamResult = new StreamResult(out);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty(OutputKeys.METHOD, "html");
serializer.transform(domSource, streamResult);
out.close();
writeFile(new String(out.toByteArray()), outPutFile);
System.out.println("Generate " + outPutFile + " with " + (System.currentTimeMillis() - startTime) + " ms.");
}
/**
* 写文件
*
* @param content
* @param path
*/
public static void writeFile(String content, String path) {
FileOutputStream fos = null;
BufferedWriter bw = null;
try {
File file = new File(path);
fos = new FileOutputStream(file);
bw = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"));
bw.write(content);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fos != null)
fos.close();
} catch (IOException ie) {
}
}
}
/**
* docx格式word转换为html
*
* @param fileName
* docx文件路径(如果你的是存到文件服务器的,直接用路径,如果是直接将文件流存到数据库的,转为InputStream )
* @param outPutFile
* html输出文件路径
* @throws TransformerException
* @throws IOException
* @throws ParserConfigurationException
*/
public static void docx2Html((String 或者InputStream看你) fileName, String outPutFile) throws TransformerException, IOException, ParserConfigurationException {
String fileOutName = outPutFile;
long startTime = System.currentTimeMillis();
//XWPFDocument document = new XWPFDocument(new FileInputStream(fileName));
XWPFDocument document = new XWPFDocument(fileName);
XHTMLOptions options = XHTMLOptions.create().indent(4);
// 导出图片
File imageFolder = new File(tempPath);
options.setExtractor(new FileImageExtractor(imageFolder));
// URI resolver
options.URIResolver(new FileURIResolver(imageFolder));
File outFile = new File(fileOutName);
outFile.getParentFile().mkdirs();
OutputStream out = new FileOutputStream(outFile);
XHTMLConverter.getInstance().convert(document, out, options);
System.out.println("Generate " + fileOutName + " with " + (System.currentTimeMillis() - startTime) + " ms.");
}
}
完整controller:
/**
*
* 预览
* @throws Exception
*/
@RequestMapping("/devDoc")
@ResponseBody
public void devDoc(String id, String type,HttpServletResponse response) throws Exception {
List<LawsStandard> findById = service.findById(id);
byte[] a = findById.get(0).getStandardAdjunct();
String fileNamepath = findById.get(0).getAdjunctName();
String fileName = fileNamepath.substring(0, fileNamepath.lastIndexOf("."));
String suffix=fileNamepath.substring(fileNamepath.lastIndexOf(".")+1);
InputStream input=null;
OutputStream out=null;
if(suffix!=null&&!"".equals(suffix)) {
if("docx".equals(suffix)) {
InputStream inputStream = new ByteArrayInputStream(a);
// File docFile = FileTObyte.byte2File(a, "E:\\" + fileNamepath, fileName);
Doc2Html.docx2Html(inputStream,"E:\\" + fileName+".html");
input=new FileInputStream("E:\\" + fileName+".html");
response.setContentType("text/html;charset=UTF-8");//解决页面显示乱码
out = response.getOutputStream();
}else if("doc".equals(suffix)) {
InputStream inputStream = new ByteArrayInputStream(a);
// File docFile = FileTObyte.byte2File(a, "E:\\" + fileNamepath, fileName);
Doc2Html.doc2Html(inputStream,"E:\\" + fileName+".html");
input=new FileInputStream("E:\\" + fileName+".html");
response.setContentType("text/html;charset=UTF-8");//解决页面显示乱码
out = response.getOutputStream();
}
else {
input=new ByteArrayInputStream(a);
response.setContentType("application/pdf");
out = response.getOutputStream();
}
}
byte[] b = new byte[512];
if(out!=null) {
if(input!=null) {
while ((input.read(b))!=-1) {
out.write(b);
}
}else {
System.out.println("InputStream为空。。。");
}
}else {
System.out.println("OutputStream为空。。。");
}
out.flush();
input.close();
out.close();
}
jsp:
不变,
//查看
function view(id){
window.open("<%=basePath%>Laws/devDoc.do?id="+id, "_blank","top=100,left=100,height=600,width=1000,status=yes,toolbar=1,menubar=no,location=no,scrollbars=yes");
}
最后,说一下那个OpenOffice
<dependency>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter</artifactId>
<version>2.2.1</version>
</dependency>
嗯,这个2.2.1不支持docx,也就是不支持2007版的,2.2.2支持,但是啊,嗯,但是,maven中央仓库没有2.2.2,你要用的话,就的手动加载啊,
还有,得下载OpenOffice服务,开启服务,才能用,你可以在程序中调用开启服务,用完随手关闭。
奉上OpenOffice的Util:
package com.htjc.longshine.Util;
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);
}
public DocConverter() {
}
/**
* 重新设置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
*/
public File doc2pdf(File docFile,File pdfFile) 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转换器异常,需要转换的文档不存在,无法转换****");
}
return pdfFile;
}
/**
* 转换成 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");
}
}
}
}
————————————————
版权声明:本文为CSDN博主「Black_Tshirt」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Black_Tshirt/article/details/81066520