1.功能:
實現Windows環境與Linux環境下文檔在線預覽功能,支持.doc、.docx、.xls、.xlsx、.ppt、.pptx、.pdf格式的文檔,對IE瀏覽器不太兼容。如要實現Linux環境下文檔在線預覽功能,改變相應配置和代碼,要安裝Linux版的OpenOffice。
2.所需組件:
(1)OpenOffice4.0.1 :
下載地址:http://pan.baidu.com/s/1hsQkhzm
(2)jquery.media.js:
下載地址:http://pan.baidu.com/s/1c2vQcCS
(3)所需jar:
下載地址:http://pan.baidu.com/s/1micCZBa
3.具體實現:
(1)設置OpenOffice的配置文件openOfficeService.properties
OO_HOME = G:/java_app_common/OpenOffice4/program/
oo_host = 127.0.0.1
oo_port =8100
(2)jsp頁面
1 <script type="text/javascript" src="/js/jquery.media.js"></script> 2 <script language="javascript"> 3 //設置預覽框的大小 4 $(function() { 5 $("#media").media({width:1000, height:950}); 6 }); 7 </script> 8 <body> 9 <div> 10 <a class="media" id="media" href="生成的pdf文件的路徑"></a> 11 </div> 12 </body>
(3)java代碼
DocConverter.java轉換類
2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.BufferedReader; 6 import java.io.File; 7 import java.io.FileInputStream; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 import java.io.InputStream; 11 import java.io.InputStreamReader; 12 import java.util.ResourceBundle; 13 14 import com.artofsolving.jodconverter.DocumentConverter; 15 import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection; 16 import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection; 17 import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter; 18 19 public class DocConverter { 20 21 private String SWFTools_Windows = "G:/java_app_common/SWFTools/pdf2swf.exe "; 22 // private String SWFTools_Linux = "F:/sortware/testingsoftware/SWFTools/pdf2swf.exe "; 23 private static final int environment = 1;// 環境1:windows,2:linux(涉及pdf2swf路徑問題) 24 private String fileString; 25 private String outputPath = "";// 輸入路徑,如果不設置就輸出在默認位置 26 private String fileName; 27 private File pdfFile; 28 private File swfFile; 29 private File docFile; 30 private File odtFile; 31 32 33 public DocConverter(String fileString) { 34 ini(fileString); 35 } 36 37 /* 38 * 重新設置 file @param fileString 39 */ 40 public void setFile(String fileString) { 41 ini(fileString); 42 } 43 44 /* 45 * 初始化 @param fileString 46 */ 47 private void ini(String fileString) { 48 try { 49 System.out.println("fileString: " + fileString); 50 this.fileString = fileString; 51 52 fileName = fileString.substring(0, fileString.lastIndexOf("/")); 53 docFile = new File(fileString); 54 String s = fileString.substring(fileString.lastIndexOf("/") + 1,fileString.lastIndexOf(".")); 55 fileName = fileName + "/" + s; 56 // 用於處理TXT文檔轉化為PDF格式亂碼,獲取上傳文件的名稱(不需要后面的格式) 57 String txtName = fileString.substring(fileString.lastIndexOf(".")); 58 // 判斷上傳的文件是否是TXT文件 59 if (txtName.equalsIgnoreCase(".txt")) { 60 // 定義相應的ODT格式文件名稱 61 odtFile = new File(fileName + ".odt"); 62 // 將上傳的文檔重新copy一份,並且修改為ODT格式,然后有ODT格式轉化為PDF格式 63 this.copyFile(docFile, odtFile); 64 pdfFile = new File(fileName + ".pdf"); // 用於處理PDF文檔 65 } else if (txtName.equals(".pdf") || txtName.equals(".PDF")) { 66 pdfFile = new File(fileName + ".bac.pdf"); 67 this.copyFile(docFile, pdfFile); 68 } else { 69 pdfFile = new File(fileName + ".pdf"); 70 //this.copyFile(docFile, pdfFile); 71 System.out.println("pdfFile: " + pdfFile.getPath()); 72 } 73 swfFile = new File(fileName + ".swf"); 74 } catch (Exception e) { 75 e.printStackTrace(); 76 } 77 } 78 79 /** 80 * @Title: copyFile 81 * @Description: TODO 82 * @param: @param docFile2 83 * @param: @param odtFile2 84 * @return: void 85 * @author: hl 87 * @throws 88 */ 89 private void copyFile(File sourceFile,File targetFile)throws Exception{ 90 //新建文件輸入流並對它進行緩沖 91 FileInputStream input = new FileInputStream(sourceFile); 92 BufferedInputStream inBuff = new BufferedInputStream(input); 93 // 新建文件輸出流並對它進行緩沖 94 FileOutputStream output = new FileOutputStream(targetFile); 95 BufferedOutputStream outBuff = new BufferedOutputStream(output); 96 // 緩沖數組 97 byte[]b = new byte[1024 * 1]; 98 int len; 99 while((len = inBuff.read(b)) != -1){ 100 outBuff.write(b,0,len); 101 } 102 // 刷新此緩沖的輸出流 103 outBuff.flush(); 104 // 關閉流 105 inBuff.close(); 106 outBuff.close(); 107 output.close(); 108 input.close(); 109 } 110 111 /* 112 * 轉為PDF @param file 113 */ 114 private void doc2pdf() throws Exception { 115 System.out.println("此文件是否存在:" + docFile.exists()); 116 if (docFile.exists()) { 117 if (!pdfFile.exists()) { 118 OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100); 119 ResourceBundle rb = ResourceBundle.getBundle("openOfficeService"); 120 String OpenOffice_HOME = rb.getString("OO_HOME"); 121 String host_Str = rb.getString("oo_host"); 122 String port_Str = rb.getString("oo_port"); 123 try { 124 // 自動啟動OpenOffice的服務 soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard 125 String command = OpenOffice_HOME 126 + "soffice -headless -accept=\"socket,host=" 127 + host_Str + ",port=" + port_Str + ";urp;\"" + "-nofirststartwizard"; 128 System.out.println("###\n" + command); 129 Process pro = Runtime.getRuntime().exec(command); 130 // 連接openoffice服務 131 // OpenOfficeConnection connection = new SocketOpenOfficeConnection( 132 // host_Str, Integer.parseInt(port_Str)); 133 connection.connect(); 134 DocumentConverter converter = new OpenOfficeDocumentConverter(connection); 135 converter.convert(docFile, pdfFile); 136 // close the connection 137 connection.disconnect(); 138 pro.destroy(); 139 System.out.println("****pdf轉換成功,PDF輸出:" + pdfFile.getPath() + "****"); 140 } catch (java.net.ConnectException e) { 141 // ToDo Auto-generated catch block 142 e.printStackTrace(); 143 System.out.println("****swf轉換異常,openoffice服務未啟動!****"); 144 doc2pdf(); 145 throw e; 146 } catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) { 147 e.printStackTrace(); 148 System.out.println("****swf轉換器異常,讀取轉換文件失敗****"); 149 doc2pdf(); 150 throw e; 151 } catch (Exception e) { 152 e.printStackTrace(); 153 doc2pdf(); 154 throw e; 155 } 156 } else { 157 System.out.println("****已經轉換為pdf,不需要再進行轉化****"); 158 } 159 } else { 160 System.out.println("****swf轉換器異常,需要轉換的文檔不存在,無法轉換****"); 161 } 162 } 163 164 /* 165 * 轉換成swf,此方法未用到 166 */ 167 @SuppressWarnings("unused") 168 private void pdf2swf() throws Exception { 169 Runtime r = Runtime.getRuntime(); 170 if (!swfFile.exists()) { 171 if (pdfFile.exists()) { 172 if (environment == 1){// windows環境處理 173 try { 174 // 這里根據SWFTools安裝路徑需要進行相應更改 175 Process p = r.exec(SWFTools_Windows + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9"); 176 //Process p = r.exec(SWFTools_Windows + pdfFile.getPath() + " -s languageedir=G:/java_app_common/xpdf/xpdf-chinese-simplified " + " -o " + swfFile.getPath() + " -T 9"); 177 178 System.out.print(loadStream(p.getInputStream())); 179 System.err.print(loadStream(p.getErrorStream())); 180 System.out.print(loadStream(p.getInputStream())); 181 System.err.println("****swf轉換成功,文件輸出:" + swfFile.getPath() + "****"); 182 // if (pdfFile.exists()) { 183 // pdfFile.delete(); 184 // } 185 } catch (Exception e) { 186 // e.printStackTrace(); 187 System.out.println("找到你了"); 188 throw e; 189 } 190 } else if (environment == 2){// linux環境處理 191 try { 192 Process p = r.exec("pdf2swf " + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9"); 193 System.out.print(loadStream(p.getInputStream())); 194 System.err.print(loadStream(p.getErrorStream())); 195 System.err.println("****swf轉換成功,文件輸出:" + swfFile.getPath() + "****"); 196 if (pdfFile.exists()) { 197 pdfFile.delete(); 198 } 199 } catch (Exception e) { 200 e.printStackTrace(); 201 throw new RuntimeException(); 202 } 203 } 204 } else { 205 System.out.println("****pdf不存在,無法轉換****"); 206 } 207 } else { 208 System.out.println("****swf已存在不需要轉換****"); 209 } 210 } 211 212 static String loadStream(InputStream in) throws IOException { 213 int ptr = 0; 214 //把InputStream字節流 替換為BufferedReader字符流 2013-07-17修改 215 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 216 StringBuilder buffer = new StringBuilder(); 217 while ((ptr = reader.read()) != -1) { 218 buffer.append((char) ptr); 219 } 220 return buffer.toString(); 221 } 222 223 /* 224 * 轉換主方法 225 */ 226 public boolean conver() { 227 // if (swfFile.exists()) { 228 // System.out.println("****swf轉換器開始工作,該文件已經轉換為swf****"); 229 // return true; 230 // } 231 232 if (environment == 1) { 233 System.out.println("****swf轉換器開始工作,當前設置運行環境windows****"); 234 } else { 235 System.out.println("****swf轉換器開始工作,當前設置運行環境linux****"); 236 } 237 238 try { 239 doc2pdf(); 240 //pdf2swf();//以前找的資料是要把PDF轉換為swf格式的文件再用flexpaper預覽,此種方法問題較多,所以沒用,改變為只轉換成pdf,然后用jquery.media.js直接預覽pdf 241 return true; 242 } catch (Exception e) { 243 // TODO: Auto-generated catch block 244 e.printStackTrace(); 245 return false; 246 } 247 248 // if (swfFile.exists()) { 249 // return true; 250 // } else { 251 // return false; 252 // } 253 } 254 255 /* 256 * 返回文件路徑 @param s 257 */ 258 public String getswfPath() { 259 if (swfFile.exists()) { 260 String tempString = swfFile.getPath(); 261 tempString = tempString.replaceAll("\\\\", "/"); 262 System.out.println(tempString); 263 264 return tempString; 265 } else { 266 return ""; 267 } 268 } 269 270 /* 271 * 設置輸出路徑 272 */ 273 public void setOutputPath(String outputPath) { 274 this.outputPath = outputPath; 275 if (!outputPath.equals("")) { 276 String realName = fileName.substring(fileName.lastIndexOf("/"), fileName.lastIndexOf(".")); 277 if (outputPath.charAt(outputPath.length()) == '/') { 278 swfFile = new File(outputPath + realName + ".swf"); 279 } else { 280 swfFile = new File(outputPath + realName + ".swf"); 281 } 282 } 283 } 284 285 public static void main(String s[]) { 286 DocConverter d = new DocConverter("G:/java_app_common/Tomcat/apache-tomcat-6.0.45/webapps/project_data/vc_space_file/1497492316364495484.docx"); 287 d.conver(); 288 } 289 }
部分controller代碼:
1 //判斷文件是否為PDF格式,如是pdf格式直接預覽,如不是pdf格式轉換成pdf格式再預覽 2 if(fileName.substring(fileName.lastIndexOf(".")).equals(".pdf") || fileName.substring(fileName.lastIndexOf(".")).equals(".PDF")) 3 { 4 //直接把此文件的路徑傳到jsp頁面 5 }else 6 { 7 //調用轉換類DocConverter,並將需要轉換的文件傳遞給該類的構造方法 8 DocConverter d = new DocConverter(文件路徑); 9 //調用conver方法開始轉換,執行doc2pdf()將office文件轉換為pdf 10 System.out.println("調用conver方法開始轉換..."); 11 d.conver(); 12 //將轉換后的pdf格式的文件的路徑傳到jsp頁面 13 }
4.在linux中配置openoffice
linux版本的openoffice:http://pan.baidu.com/s/1slK3WK1
(1)安裝openoffice,網上安裝教程很多,這里不再多說。
(2)修改配置文件openOfficeService.properties中 OO_HOME的路徑。
(3)進入openoffice的安裝目錄:
cd /opt/openoffice4/program
執行命令啟動openoffice:./soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard &
(4)處理中文轉PDF亂碼問題:
1)在linux中的 /usr/share/fonts目錄下新建一個fallback文件夾,將Windows中的字體全部拷貝到fallback中。
Windows中的字體在C:\Windows\Fonts目錄下。
然后執行命令:
mkfontscale
mkfontdir
fc-cache
2)關閉openoffice,重新啟動openoffice:
關閉openoffice的所有相關的進程: ps -ef|grep soffice.bin|grep -v grep|cut -c 9-15|xargs kill -9
查看8100端口是否啟用:netstat -pln
如未看到8100端口的信息,說明已成功關閉openoffice。
執行命令啟動openoffice:./soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard &
查看8100端口是否啟用:netstat -pln
如看到8100端口的信息,說明已成功啟動openoffice。
3)如按上述操作執行后還有亂碼,解決方法如下:
找到linux中jdk的安裝位置,進入jdk中的jre中的lib下的fonts文件夾,如:cd /data/jdk1.6.2_27/jre/lib/fonts,執行上述(4)中1)的操作。
找到openoffice的安裝目錄,進入openoffice4/share/fonts/truetype目錄,執行上述(4)中1)的操作。
再執行(4)中2)的操作。