文件在線預覽doc,docx轉換pdf(一)
1. 前言
文檔轉換是一個是一塊硬骨頭,可是也是必不可少的,咱們正好作的知識庫產品中,也面臨着一樣的問題,文檔轉換,精準的全文搜索,知識的轉換率,是知識庫產品的基本要素,初識閱讀時同時絞盡腦汁,本身開發?,集成第三方?都是中小企業面臨的一大難題…….
本身在網上搜索着找到poi開源出來的不少例子,最開始是用poi把全部文檔轉換爲html,
1) 在github上面找到一個https://github.com/litter-fish/transform完整的demo,你想要的轉換基本都提供,初學者能夠參照實現轉換出來的基本樣子,達到通用級別,須要本身花不少功夫。此開源代碼是基於poi和itext(pdf)的轉換方式。
2) https://gitee.com/kekingcn/file-online-preview這是開源中國提供的一個源碼,基於jodconverter,原理是調用windows,另存爲的組件,實現轉換。
3) 收費產品例如【永中office】【office365】【idocv】、【https://downloads.aspose.com/words/java】
2. 轉換思路
本身在嘗試過不少後,也與永中集成了文檔轉換,發現,要想完成預覽的品質,必須的作二次渲染。畢竟永中作了十幾年文檔轉換咱們不能比的,本身琢磨後,發現一個勉強靠譜的思路,doc和docx都轉換爲pdf實現預覽。都是在基於poi的基礎上。
2.1. Doc轉換pdf
1) Doc轉換爲xml
/** * doc轉xml */ public String toXML(String filePath){ try{ POIFSFileSystem nPOIFSFileSystem = new POIFSFileSystem(new File(filePath)); HWPFDocument nHWPFDocument = new HWPFDocument(nPOIFSFileSystem); WordToFoConverter nWordToHtmlConverter = new WordToFoConverter( DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); PicturesManager nPicturesManager = new PicturesManager() { public String savePicture(byte[] arg0, PictureType arg1,String arg2, float arg3, float arg4) { //file:///F://20.vscode//iWorkP//temp//images//0.jpg //System.out.println("file:///"+PathMaster.getWebRootPath()+ java.io.File.separator + "temp"+java.io.File.separator+"images" + java.io.File.separator + arg2); // return "file:///"+PathMaster.getWebRootPath()+java.io.File.separator +"temp"+java.io.File.separator+"images" + java.io.File.separator + arg2; return "file:///"+PathMaster.getWebRootPath()+java.io.File.separator +"temp"+java.io.File.separator+"images" + java.io.File.separator + arg2; } }; nWordToHtmlConverter.setPicturesManager(nPicturesManager); nWordToHtmlConverter.processDocument(nHWPFDocument); String nTempPath = PathMaster.getWebRootPath() + java.io.File.separator + "temp" + java.io.File.separator + "images" + java.io.File.separator; File nFile = new File(nTempPath); if (!nFile.exists()) { nFile.mkdirs(); } for (Picture nPicture : nHWPFDocument.getPicturesTable().getAllPictures()) { nPicture.writeImageContent(new FileOutputStream(nTempPath + nPicture.suggestFullFileName())); } Document nHtmlDocument = nWordToHtmlConverter.getDocument(); OutputStream nByteArrayOutputStream = new FileOutputStream(OUTFILEFO); DOMSource nDOMSource = new DOMSource(nHtmlDocument); StreamResult nStreamResult = new StreamResult(nByteArrayOutputStream); TransformerFactory nTransformerFactory = TransformerFactory.newInstance(); Transformer nTransformer = nTransformerFactory.newTransformer(); nTransformer.setOutputProperty(OutputKeys.ENCODING, "GBK"); nTransformer.setOutputProperty(OutputKeys.INDENT, "YES"); nTransformer.setOutputProperty(OutputKeys.METHOD, "xml"); nTransformer.transform(nDOMSource, nStreamResult); nByteArrayOutputStream.close(); return ""; }catch(Exception e){ e.printStackTrace(); } return ""; }
2) Xml轉換爲pdf
這裏我是使用fop經過xml轉換爲pdf,也是最近欣喜的一個發現,poi官網推薦的我一直沒去仔細看,裏面的架包和永中的不少高清包,如出一轍,如今貌似路子對了。有興趣者研究去吧。個人源碼已經在githubhttps://github.com/liuxufeijidian/file.convert.master/tree/master上面,環境已經配置好,須要準備好doc和docx文檔便可。
/* * xml 轉pdf */ public void xmlToPDF() throws SAXException, TransformerException{ // Step 1: Construct a FopFactory by specifying a reference to the configuration file // (reuse if you plan to render multiple documents!) FopFactory fopFactory = null; new URIResolverAdapter(new URIResolver(){ public Source resolve(String href, String base) throws TransformerException { try { URL url = new URL(href); URLConnection connection = url.openConnection(); connection.setRequestProperty("User-Agent", "whatever"); return new StreamSource(connection.getInputStream()); } catch (IOException e) { throw new RuntimeException(e); } } }); OutputStream out = null; try { fopFactory = FopFactory.newInstance(new File(CONFIG)); // Step 2: Set up output stream. // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams). out = new BufferedOutputStream(new FileOutputStream(OUTFILEPDF)); // Step 3: Construct fop with desired output format Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out); // Step 4: Setup JAXP using identity transformer TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); // identity transformer // Step 5: Setup input and output for XSLT transformation // Setup input stream Source src = new StreamSource(OUTFILEFO); // Resulting SAX events (the generated FO) must be piped through to FOP Result res = new SAXResult(fop.getDefaultHandler()); // Step 6: Start XSLT transformation and FOP processing transformer.transform(src, res); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { //Clean-up try { out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
2.1.3
不少時候咱們是使用word直接轉的html,可是須要本身寫二次渲染的代碼,較爲複雜,我是使用迂迴方法,doc轉xml,再用xml轉換pdf,轉換出來的pdf用pdfjs渲染便可實現和瀏覽器打開同樣的預覽,pdfjs預覽方法詳情見https://blog.csdn.net/liuxufeijidian/article/details/82260199
ending:你們都想看效果如何,https://github.com/litter-fish/transform,github獲取改源碼,配置好doc和docx文檔便可實現轉換,接下來會繼續努力不間斷優化和更新文檔轉換。