相關專題鏈接
前言:最近參與了一個項目,客戶要求把系統所有用戶提交的所有電子文件(主要是word、Excel、圖片等)都轉化為PDF格式保存,並且要能支持在線查看、自動加簽(添加圖片印章、數字證書)等功能,因為之前也沒有接觸這方面的知識在項目開發過程中也是遇到了諸多困難,但慶幸的是通過自己研究、百度等方法得到了解決,最后的效果還算令人滿意,趁現在項目比較空閑把整個實現方案做個介紹。
一、demo效果圖
選擇文件提交后,在后台先轉成pdf文件,然后再轉化為swf文件在前台展示! demo比較簡陋,沒做太多修飾,主要是為了說明問題,大家不要在意這些細節!demo中用到的部分軟件在下面下載區有鏈接,下載解壓放在C盤即可。
二、文件上傳
1、前台部分
前台采用form表單、隱藏iframe實現無刷新上傳:
js部分代碼
<script type="text/javascript" src="js/jquery-1.8.0.min.js"></script> <script type="text/javascript"> //支持的文件上傳類型 var accept_extend = ['jpg', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'bmp', 'jpeg', 'png', 'gif']; var basePath = "<%=basePath%>"; /** * 校驗文件擴展名 * @param {Object} t_ext 文件擴展名 * @return {TypeName} 校驗是否通過 */ function checkFileExtendName(t_ext) { var flag = false; if (t_ext != '') { var length = accept_extend.length; for (var i = 0; i < length; i++) { if (t_ext == accept_extend[i]) flag = true; } } return flag; } /** * 文件上傳方法 */ function upload() { //校驗 var file = document.getElementById("file").value; if(file == undefined || file == null || file == "" ) { alert("請選擇文件!"); return; } var type = file.slice(file.lastIndexOf('.')+1); if(!checkFileExtendName(type.toLowerCase())) { alert("文件類型不支持!"); return; } //提交 var form = document.getElementById('upload_form'); form.submit(); //提交按鈕控制 $('#uploadBtn').attr('disabled', 'disabled'); $('#loading').css('display', ''); //獲取寫入隱藏iframe的上傳結果 $("#iframe").load(function () { var contents = $(this).contents().get(0); var data = $(contents).find('body').html(); data = window.eval('(' + data + ')'); if(data.rtncode == 2000) { //上傳成功后提示並展示swf區域 alert(data.name + "上傳成功!"); $("#iframe_pdf_view").width($('body').width() * 0.97).height($('body').height() * 0.85); $("#iframe_pdf_view").attr("src", basePath + "fileview.jsp?path=" + data.path); } $('#uploadBtn').removeAttr('disabled'); $('#loading').css('display', 'none'); $("#iframe").off("load"); }); } </script>
html部分代碼
此處需要注意:文件上傳時form表單屬性enctype="multipart/form-data"后台才能獲取文件流,屬性target="iframe"需指向隱藏iframe的name才能實現無刷新上傳。
<div style="background-color:#BDD8F2;margin-left:40%;margin-top:20px;border-style:double;margin-right:35%"> <div style="margin-top:10px;margin-left:10px"> <!-- from的target需指向隱藏iframe的name --> <form id="upload_form" action="commonServlet?type=upload" method="post" enctype="multipart/form-data" target="iframe" > <input id="file" type="file" name="file" /> <img id="loading" src="images/loading.gif" style="display:none"> <input id="uploadBtn" type="button" value="提交" onclick="upload()"/> </form> <iframe id="iframe" name="iframe" style="width:0px;height:0px"></iframe> </div> </div> <iframe id="iframe_pdf_view" scrolling="auto" frameborder="0" marginheight="0" marginwidth="0"></iframe>
2、后台代碼:
后台使用Apache的fileupload包和IO包來解析請求獲取文件流:
PrintWriter out = response.getWriter(); // 創建文件處理工廠,它用於生成FileItem對象。 DiskFileItemFactory difactory = new DiskFileItemFactory(); // 設置緩存大小,如果上傳文件超過緩存大小,將使用臨時目錄做為緩存。 difactory.setSizeThreshold(1024 * 1024 * 5); String dir = this.getServletContext().getRealPath("/");//應用目錄 // 設置處理工廠緩存的臨時目錄,此目錄下的文件需要手動刪除。 File filedir = new File(dir + "file/temp"); if (!filedir.exists()) { filedir.mkdirs(); } difactory.setRepository(filedir); // 設置文件實際保存的目錄 File fudir = new File(dir + "file/upload"); if (!fudir.exists()) { fudir.mkdirs(); } //創建request的解析器,它會將數據封裝到FileItem對象中。 ServletFileUpload sfu = new ServletFileUpload(difactory); sfu.setHeaderEncoding("GBK"); //解析保存在request中的數據並返回list集合 List<FileItem> list = null; try { list = sfu.parseRequest(request); } catch (FileUploadException e) { e.printStackTrace(); out.print("{rtncode:2001,message:'" + e.getMessage() + "'}"); out.flush(); out.close(); return; } String filename = null; InputStream in = null; FileOutputStream fos = null; if (list != null && list.size() > 0)// 遍歷list集合,取出每一個輸入項的FileItem對象,並分別獲取數據 { for (Iterator<FileItem> it = list.iterator(); it.hasNext();) { FileItem fi = (FileItem) it.next(); if (fi.isFormField())//判斷是否為表單屬性 { continue; } String originalName = fi.getName();//原始文件名 String extendName = originalName.substring(originalName .lastIndexOf(".") + 1);//獲取原始文件擴展名 filename = UUID.randomUUID().toString() + ".pdf";//新文件名 //獲取上傳文件流 in = fi.getInputStream(); String pdfPath = dir + "file/upload/" + filename;//生成的PDF路徑 fos = new FileOutputStream(pdfPath);//創建文件輸出流 //文件轉PDF處理 if (Constans.FileExtName.DOC.equalsIgnoreCase(extendName) || Constans.FileExtName.DOCX .equalsIgnoreCase(extendName) || Constans.FileExtName.XLS .equalsIgnoreCase(extendName) || Constans.FileExtName.XLSX .equalsIgnoreCase(extendName)) { // 調用openoffice轉換office文件為PDF並存放到指定目錄 PDFUtil.converterOffiec2PDF(in, fos, extendName); } else if (Constans.FileExtName.PDF.equalsIgnoreCase(extendName)) { // 上傳pdf文件到指定目錄 PDFUtil.uploadPDF(in, fos); } else { PDFUtil.converterImg2Pdf(in, fos); } fi.delete();// 文件刪除前需要關閉流 //調用swftools轉換PDF為swf文件 if(PDFUtil.convert2SWF(pdfPath)) { out.print("{rtncode:2000,message:'success',name:'" + originalName.substring(0, originalName .lastIndexOf(".")) + "',path:'" + filename.replaceAll(".pdf", ".swf") + "'}"); } else { out.print("{rtncode:2001,message:'error'}"); } out.flush(); out.close(); } }
相關文件下載地址
PDF解決方案demo: http://pan.baidu.com/s/1i3mmwux
swftools、xpdf:http://pan.baidu.com/s/1dDu1Yoh(注:解壓放在C盤根目錄即可)