Java 实现word pdf在线预览

Java 实现word pdf在线预览

最近项目有这个需求,查找了一些资料,在这整理一下。

首先,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");  
            }  
        }  
    }  
  


}

猜你喜欢

转载自blog.csdn.net/Black_Tshirt/article/details/81066520