网上虽然有各种在线文档制作的教程但却没有一个集大成的,经过小亮同学不辞辛苦勤奋耕耘下终于制作出了相关的雏形,然后在下在稍加润色,这样一篇完整的博客便横空出世了- -, 下面则是分类进行介绍。
在分开介绍前先给出后台的文件控制函数,这个函数就是简单的根据请求参数中包含的文件类型来具体调用相关的方法。代码如下:
/** * 文件显示的控制函数,由此来判断文件类型并调用相关方法 * @return */ public String lookUpfileValue(){ //获取web上下文对象 ServletContext sc = ServletActionContext.getServletContext(); //获得服务器上文件所在地址 String realPath = sc.getRealPath("/upload"); //获得文件全路径 String filePath = realPath + File.separatorChar +ftObj.getStoreFileName() ; String strFileName = ftObj.getStoreFileName().substring(0, ftObj.getStoreFileName().lastIndexOf(".")); //获得文件扩展名 String extensions =ftObj.getStoreFileName().substring(ftObj.getStoreFileName().lastIndexOf("."),ftObj.getStoreFileName().length()); //创建FileTable该类用来封装文件的属性包括作者,文件名等 FileTable fileTableObj=new FileTable(); String filename1 =strFileName.substring(0,strFileName.length()-13); fileTableObj.setFileName(filename1); fileTableObj.setAuthor(ftObj.getAuthor()); ftObj =fileTableObj; /** * 以下为根据后缀判断文件类型并进行方法调用 */ try { //如果是excel文件 if(extensions.equals(".xls")){ //获得文件放置路径 String fWPath = sc.getRealPath("/fileManagement"); fWPath = fWPath+"\"; //生成临时文件的字符串 String fWPath2 =fWPath+ "temp.pdf"; try { //保存临时文件 saveExcelAsPdf(filePath,fWPath2); //创建临时 File file=new File(fWPath2); //将Pdf转成图片 pdfStrList =reapdf(file,realPath); System.gc(); //删除临时文件 boolean success = file.delete(); System.out.println(success); } catch (Throwable e) { } return "lookupPdf"; }else if(extensions.equals(".doc")){ String fWPath = sc.getRealPath("/fileManagement"); try { readword(filePath,fWPath); } catch (Throwable e) { } }else if(extensions.equals(".pdf")){ File fobj = new File (filePath); fname = FileTableAction.getTextFromPdf(filePath); pdfStrList =reapdf(fobj,realPath); return "lookupPdf"; }else{ fname = FileTableAction.readTxt(filePath); return "lookupnohtml"; } } catch (Exception e) { } return "lookup"; }
该方法注释写的很清楚在这里不多做解释。
1.制作txt在线文档
txt 文档相对来说比较简单,因为基本都是文本的东西,这里先说明下展示的逻辑,我们将服务器上的文本文档经后台读入到缓存中染后经过控制的bean传送到前台界面显示。
/** * 读取txt文档的方法 * @param txt * @return */ public static String readTxt(String txt){ StringBuffer sb = new StringBuffer(); try { // 创建文件字符流对象 FileReader read = new FileReader(new File(txt)); //创建字符缓存 char ch[] = new char[1024]; //将文件读入到缓存 int d = read.read(ch); while(d!=-1){ String str = new String(ch,0,d); sb.append(str); d = read.read(ch); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return sb.toString(); }
这里只是单纯将文本文档的内容读取出来传值到前台,并无其他难点。前台部分界面接收值的样式如下<textarea>${news.newsContent}</textarea>,可以看到读出来的文本文档被封装为news实体的一个field。
2.制作word在线文档
这里是把word 转成jsp 后显示,其余的前端界面请自行百度。相关java后台代码如下
//读起word文档 public static void readword(String filepath,String fwpath) throws Throwable{ //获得文件的路径 String path = filepath.substring(0,filepath.lastIndexOf("\"))+"\"; //创建输入流 InputStream input = new FileInputStream(filepath); //创建HWPFDocument对象,这里用了第三方的插件poi HWPFDocument wordDocument = new HWPFDocument(input); //创建word到html的转换对象 WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); //设置word到html的转换对象的图像管理属性 wordToHtmlConverter.setPicturesManager(new PicturesManager() { public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float widthInches, float heightInches) { return suggestedName; } }); wordToHtmlConverter.processDocument(wordDocument); //获得该word中所有的图片 List pics = wordDocument.getPicturesTable().getAllPictures(); if (pics != null) { for (int i = 0; i < pics.size(); i++) { Picture pic = (Picture) pics.get(i); try { pic.writeImageContent(new FileOutputStream(path + pic.suggestFullFileName())); } catch (FileNotFoundException e) { e.printStackTrace(); } } } //由 word到html的转换对象创建dom对象 Document htmlDocument = wordToHtmlConverter.getDocument(); //创建字节输出输出流 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); //创建dorm的数据源对象 DOMSource domSource = new DOMSource(htmlDocument); //创建结果输出流 StreamResult streamResult = new StreamResult(outStream); //创建转化工厂 TransformerFactory tf = TransformerFactory.newInstance(); Transformer serializer = tf.newTransformer(); /** * 以下为编码,样式的属性设置 */ serializer.setOutputProperty(OutputKeys.ENCODING, "GBK"); serializer.setOutputProperty(OutputKeys.INDENT, "yes"); serializer.setOutputProperty(OutputKeys.METHOD, "html"); serializer.transform(domSource, streamResult); outStream.close(); //获得内容的字符串对象 String content = new String(outStream.toByteArray()); String temp = "<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><br> <%@taglib prefix="s" uri="/struts-tags"%>"; temp =temp + content.replace("<img src="","<img src=""+"${pageContext.request.contextPath}/upload/"); // System.out.println(temp); String itemp = temp.replace("</style>", ".SelectId{" + "-webkit-user-select:none; /* Webkit */ " + " -moz-user-select:none; /* Firefox */" + " -ms-user-select:none; /* IE10+ */ " + "} </style>"); itemp = itemp.replace("<body class="b1 b2">", "<body class="b1 b2"> <div style="margin-left:100px;;margin-top:20px;" class="SelectId">"); itemp =itemp.replace("</body>", "</div> </body>"); //写回文件到前端显示 FileUtils.write(new File(fwpath, "abc.jsp"), itemp, "utf-8"); }
这里需要用Poi的第三软类库来完成对word文件的"拆分",然后根据自己的需要将获得的拆分元素写回前端显示。
3.制作pdf在线文档
这里采取了一种折中的办法,先把pdf转化为图片然后在页面读取,这个办法好像不是特别好,所以如果能找到更好的办法请联系本人,
这里同样要引入第三方类库itextpdf-5.3.5.jar java代码如下
//生成pdf生成图片 public static List<String> reapdf(File file,String upleadpath) throws IOException { List<String> strlist = new ArrayList<String>(); //创建随即读取文件留 RandomAccessFile raf = new RandomAccessFile(file, "r"); FileChannel channel = raf.getChannel(); ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel .size()); //创建PDF文件对象 PDFFile pdffile = new PDFFile(buf); //显示Pdf文件页数 System.out.println("页数: " + pdffile.getNumPages()); //根据页数生成图片 for (int i = 1; i <= pdffile.getNumPages(); i++) { // 创建pdf 页对象 PDFPage page = pdffile.getPage(i); // 获得图片的宽度和长度 Rectangle rect = new Rectangle(0, 0, (int) page.getBBox() .getWidth(), (int) page.getBBox().getHeight()); // 创建文件对象 Image img = page.getImage(rect.width*2, rect.height*2, // width & rect, // clip rect null, // null for the ImageObserver true, // fill background with white true // block until drawing is done ); //创建图片缓存 BufferedImage tag = new BufferedImage(rect.width*2, rect.height*2, BufferedImage.TYPE_INT_RGB); tag.getGraphics().drawImage(img, 0, 0, rect.width*2, rect.height*2, null); FileOutputStream out = new FileOutputStream( upleadpath+"\"+ i + ".jpg"); // 输出到文件流 strlist.add(i + ".jpg"); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(tag); // JPEG编码 out.close(); buf.clear(); channel.close(); raf.close(); } return strlist; }
对Pdf文档的转化同样使用专门的处理类库将pdf分解为单页的图片传到前端显示,代码内容注释给出,在这里不多做废话。下面详细说明下excel转化为在线文档,这个比较复杂,涉及到两种类型:一种是没有图片的,一种是有图片的。这里同样跟word一样使用了poi的第三方类库
4.1Excel 转jsp 用poi 没有图片的
//读起excel文档 public static void readexcel(String filepath,String fwpath) throws Throwable{ //定义HSSFWorkbook对象 HSSFWorkbook workbook; File f = new File(filepath); try { //根据文件路径获得HSSFWorkbook对象 workbook = ExcelToHtmlUtils.loadXls( f ); } catch ( Exception exc ) { return; } //获得excel转化Html对象 ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter( DocumentBuilderFactory.newInstance().newDocumentBuilder() .newDocument() ); excelToHtmlConverter.processWorkbook(workbook ); //创建写出对象 StringWriter stringWriter = new StringWriter(); /** * 设置转化的样式 */ Transformer transformer = TransformerFactory.newInstance() .newTransformer(); transformer.setOutputProperty( OutputKeys.ENCODING, "GBK" ); transformer.setOutputProperty( OutputKeys.INDENT, "no" ); transformer.setOutputProperty( OutputKeys.METHOD, "html" ); transformer.transform( new DOMSource( excelToHtmlConverter.getDocument() ), new StreamResult( stringWriter ) ); /** * 以下雷同word转化方法 */ String temp = "<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><br> <%@taglib prefix="s" uri="/struts-tags"%>"; temp =temp +stringWriter.toString(); temp = temp.replace("<img src="","<img src=""+"${pageContext.request.contextPath}/upload/"); String itemp = temp.replace("</style>", ".SelectId{" + "-webkit-user-select:none; /* Webkit */ " + " -moz-user-select:none; /* Firefox */" + " -ms-user-select:none; /* IE10+ */ " + "} </style>"); itemp = itemp.replace("<body class="b1">", "<body class="b1"> <div style="margin-left:100px;;margin-top:20px;" class="SelectId">"); itemp=itemp.replace("</body>", "</div> </body>"); FileUtils.write(new File(fwpath, "abc.jsp"), itemp, "utf-8"); }
以上的方法同word转化在线文档差不多再次不多做解释。
4.2有图片的 用jacob做的 吧excel转成pdf 在pdf 转图片 pdf在转图片上面有就不说了你可以下载jacob-1.15;
转化思路为excel-pdf-在线文档(html,jsp)等
//根据时间生成文件名的方法(其实完全可以用uuid生成) public String getDateStr() { Calendar cl = Calendar.getInstance(); cl.setTime(new Date()); String str = cl.get(Calendar.YEAR) + "" + (cl.get(Calendar.MONTH) + 1) + "" + cl.get(Calendar.DATE) + "" + cl.get(Calendar.HOUR) + "" + cl.get(Calendar.MINUTE) + "" + cl.get(Calendar.SECOND); return str; }
下面为具体转化细节
private String path; public static boolean runFlag = false; public void saveExcelAsPdf(String filePath, String outFile) { ComThread.InitSTA(); //根据pid获得ActiveXComponent对象,这个pid对应在你的注册表中,如果没有说明你的电脑上的office //未安装或安装出问题,需要重新安装,否则该程序不能用 ActiveXComponent actcom = new ActiveXComponent("Excel.Application"); Dispatch excel = null; try { /** * 以下为对excel文档的操作,来自网上的资料笔者亦不懂其中的意思 */ System.out.println((new Date()).toString() + " start convert from : " + filePath + " to " + outFile); actcom.setProperty("Visible", new Variant(false)); Dispatch excels = actcom.getProperty("Workbooks").toDispatch(); excel = Dispatch.invoke( excels, "Open", Dispatch.Method, new Object[] { filePath, new Variant(false), new Variant(false) }, new int[9]).toDispatch(); Dispatch.invoke(excel, "SaveAs", Dispatch.Method, new Object[] { outFile, new Variant(57), new Variant(false), new Variant(57), new Variant(57), new Variant(false), new Variant(true), new Variant(57), new Variant(false), new Variant(true), new Variant(false) }, new int[1]); } catch (Exception es) { es.printStackTrace(); } finally { Dispatch.call(excel, "Close", new Variant(false)); if (actcom != null) { actcom.invoke("Quit", new Variant[] {}); actcom = null; } ComThread.Release(); } } /** * 该方法批次将excel文档转化为pdf文档,之后pdf文档的显示已经在上面介绍中给出。 */ public void listAllFile() { runFlag = true; String fileName = "", appdex = ""; File temp = null; try { File[] list = new File(path).listFiles(new FileFilter() { public boolean accept(File pathname) { boolean x = false; if (pathname.getName().toLowerCase().endsWith(".xls")) { x = true; } return x; } }); System.out.println((new Date()).toString() + " Total Convert File : " + list.length); for (int i = 0; i < list.length; i++) { fileName = list[i].getName().substring(0, list[i].getName().indexOf(".")); appdex = list[i].getName().substring(list[i].getName().indexOf(".")); temp = new File(path + fileName + ".pdf"); if (temp.exists()) { temp.renameTo(new File(path + fileName + "-" + getDateStr() + ".pdf")); } saveExcelAsPdf(path + fileName + appdex, path + fileName + ".pdf"); } } catch (Exception ex) { ex.printStackTrace(); } runFlag = false; }
以上为本文的全部内容,虽然山寨的意味很弄,但总归能够实现在线文档的功能,希望以后找到更完美的解决方案再与大家共享。(补充下:这里使用了第三方类库poi 实现excel和word的在线显示,关于对该类库的调用方法还有讲究,下载的dll 文件必须入你的机器类型兼容,也就是要区分好64位和32位的,再有就是你的office一定要装好,并写入到到注册表里,最后就是excel转化pdf的时候需要在本地服务器上安装SaveAsPDFandXPS.exe的插件才能完成相关转换,这个插件可以自行百度下载)。