基于SSM 的 Office 在线编辑

xiaoxiao2021-02-28  118

Office在线编辑功能在OA系统中经常被使用。本文主要介绍在SSM框架下利用Java整合Office Online Server 2016 (OOS) 进行office 在线编辑。OOS的环境搭建之前文章有过介绍,在这里不进行过多的阐述。具体的代码实现如下:

Java 实现WOPI协议:

package com.officeonline; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URLDecoder; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.Filter; import javax.servlet.FilterConfig; /** * Servlet implementation class wopi */ @WebFilter("/wopi/*") public class OfficeFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // System.out.println("权限"+request.getParameterValues("power")); HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String power = httpRequest.getParameter("power"); String uri = httpRequest.getRequestURI(); //获取完整的Url请求路径 // 解决中文乱码问题 String fileUri = URLDecoder.decode(uri.substring(uri.indexOf("/wopi/") + 1, uri.length()), "UTF-8"); String filePath = request.getServletContext().getRealPath("/") + fileUri; if (fileUri.endsWith("/contents")) { // GetFile :返回文件流 filePath = filePath.substring(0, filePath.indexOf("/contents")); String method = httpRequest.getMethod(); if (method.equals("GET")) { getFile(filePath, httpResponse); } if (method.equals("POST")) { postFile(filePath, httpRequest); } } else { // CheckFileInfo :返回json response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=UTF-8"); PrintWriter out = null; try { out = response.getWriter(); out.write(FileUtils.checkFileInfo(filePath, power)); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { out.close(); } } } return; } private HttpServletResponse getFile(String path, HttpServletResponse response) { try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); String contentType = "application/octet-stream"; // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 设置response的Header response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("utf-8"), "ISO-8859-1")); response.addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType(contentType); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); } return response; } public static byte[] getRequestPostBytes(HttpServletRequest request) throws IOException { int contentLength = request.getContentLength(); if (contentLength < 0) { return null; } byte buffer[] = new byte[contentLength]; for (int i = 0; i < contentLength;) { int readlen = request.getInputStream().read(buffer, i, contentLength - i); if (readlen == -1) { break; } i += readlen; } return buffer; } public void postFile(String path, HttpServletRequest request) { // 文件的路径 File file = new File(path); try { if (!file.exists()) { file.createNewFile();// 构建文件 } String submitMehtod = request.getMethod(); if (submitMehtod.equalsIgnoreCase("post")) { byte[] bytes = getRequestPostBytes(request); FileOutputStream fop = new FileOutputStream(file); fop.write(bytes); fop.flush(); fop.close(); } } catch (IOException e) { e.printStackTrace(); } } @Override public void destroy() { // TODO Auto-generated method stub } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }

OfficeFilter 中引用的FileUtils类:

package com.officeonline; import java.io.File; public class FileUtils { /** * 获取文件基本信息 * * @param filePath * 文件路径 * @return */ public static String checkFileInfo(String filePath, String power) { File file = new File(filePath); // String hash=null; String baseFileName = null; // 文件名 String ownerId = null; // 文件所有者的唯一编号 long size = 0; // 文件大小,以bytes为单位 String sha256 = null; // 文件的256位bit的SHA-2编码散列内容 long version = 0; // 文件版本号,文件如果被编辑,版本号也要跟着改变 boolean Write = false; boolean Print = true; // 在网页中获取用户是否有权限编辑和打印,根据获取的参数设置office的功能 if (power == null) { Write = false; Print = true; } else { if (power.equals("write")) { Write = true; } if (power.equals("print")) { Print = false; } if (power.equals("writeprint") || power.equals("printwrite")) { Write = true; Print = false; } } if (file.exists()) { // 取得文件名。 baseFileName = file.getName(); size = file.length(); // 取得文件的后缀名。 ownerId = "admin"; version = file.lastModified(); sha256 = new Encrypt().SHA256(baseFileName); } return "{\"DisablePrint\":\"" + Print + "\",\"SupportsLocks\":\"" + true + "\",\"Sha256\":\"" + sha256 + "\",\"SupportsUpdate\":\"" + true + "\",\"UserCanWrite\":\"" + Write + "\",\"BaseFileName\":\"" + baseFileName + "\",\"OwnerId\":\"" + ownerId + "\",\"Size\":\"" + size + "\",\"AllowExternalMarketplace\":\"" + true + "\",\"Version\":\"" + version + "\"}"; } } FileUtils类中的Encrypt类:

package com.officeonline; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Encrypt { /** * 传入文本内容,返回 SHA-256 串 * * @param strText * @return */ public String SHA256(final String strText) { return SHA(strText, "SHA-256"); } /** * 传入文本内容,返回 SHA-512 串 * * @param strText * @return */ public String SHA512(final String strText) { return SHA(strText, "SHA-512"); } /** * 字符串 SHA 加密 * * @param strSourceText * @return */ private String SHA(final String strText, final String strType) { // 返回值 String strResult = null; // 是否是有效字符串 if (strText != null && strText.length() > 0) { try { // SHA 加密开始 // 创建加密对象 并傳入加密類型 MessageDigest messageDigest = MessageDigest.getInstance(strType); // 传入要加密的字符串 messageDigest.update(strText.getBytes()); // 得到 byte 類型结果 byte byteBuffer[] = messageDigest.digest(); // 將 byte 轉換爲 string StringBuffer strHexString = new StringBuffer(); // 遍歷 byte buffer for (int i = 0; i < byteBuffer.length; i++) { String hex = Integer.toHexString(0xff & byteBuffer[i]); if (hex.length() == 1) { strHexString.append('0'); } strHexString.append(hex); } // 得到返回結果 strResult = strHexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } return strResult; } } controller层实现对word(模板)的复制和对复制后文件的修改:

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import util.UrlCode; @Controller public class OfficeController { @RequestMapping(value = "/openmodle.do") @ResponseBody public String openmodel(HttpServletRequest request, HttpServletResponse response) throws IOException { String filePath = request.getServletContext().getRealPath("/"); FileInputStream fis = new FileInputStream(filePath + "wopi/files/fs/t1.docx");//t1.docx为模板文件 FileOutputStream fos = new FileOutputStream(filePath + "wopi/files/fs/t2.docx");//t2.docx为按照末班新建的文件 BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); int by = 0; byte[] buf = new byte[104857600];//默认上传最大文件为100M while ((by = bis.read(buf)) != -1) { bos.write(buf, 0, by); } fis.close(); fos.close(); bis.close(); bos.close(); String Wopisrc=UrlCode.url("http://xx.xx.xx.xx:8080/SmartSchool/wopi/files/fs/t2.docx?power=write"); return "http://xx.xx.xx.xx/we/wordeditorframe.aspx?WOPISrc="+Wopisrc; } } Html页面的实现:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Office 在线</title> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript"> function openmodle() { filename = prompt("请输入新建文件名:","新建文件"); if (filename != null){ alert(">>>>>>>>>>>>>>>>>>>>>"+filename+">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); $.ajax({ url : "openmodle.do", data : JSON.stringify(filename),//用户新建文件的文件名传到前台 type : "POST", success : function(msg) { console.log("成功"); console.log(msg); window.open(msg); }, error : function(data, textStatus, errorThrown) { console.log("失败"); }, }); }else{ alert("你按了[取消]按钮"); } } </script> </head> <body> <a href="#"οnclick="openmodle()">通过模板发布文件</a> <table> <tr><td>Word<td><td><a href="http://xx.xx.xx.xx/wv/wordviewerframe.aspx?WOPISrc=http://xx.xx.xx.xx:8080/SmartSchool/wopi/files/1.docx">预览</a><td><td><a href="http://xx.xx.xx.xx/we/wordeditorframe.aspx?WOPISrc=http://xx.xx.xx.xx:8080/SmartSchool/wopi/files/1.docx?power=write">编辑</a><td></tr> <tr><td>Excel<td><td><a href="http://xx.xx.xx.xx/x/_layouts/xlviewerinternal.aspx?WOPISrc=http://xx.xx.xx.xx:8080/SmartSchool/wopi/files/1.xlsx">预览</a><td><td><a href="http://xx.xx.xx.xx/x/_layouts/xlviewerinternal.aspx?edit=1&WOPISrc=http://xx.xx.xx.xx:8080/SmartSchool/wopi/files/1.xlsx?power=write">编辑</a><td></tr> <tr><td>Ppt<td><td><a href="http://xx.xx.xx.xx/p/PowerPointFrame.aspx?WOPISrc=http://xx.xx.xx.xx:8080/SmartSchool/wopi/files/1.pptx">预览</a><td><td><a href="http://xx.xx.xx.xx/p/PowerPointFrame.aspx?PowerPointView=EditView&WOPISrc=http://xx.xx.xx.xx:8080/SmartSchool/wopi/files/1.pptx?power=write">编辑</a><td></tr> <tr><td>Pdf<td><td><a href="http://xx.xx.xx.xx/wv/wordviewerframe.aspx?PdfMode=1&WOPISrc=http://xx.xx.xx.xx:8080/SmartSchool/wopi/files/1.pdf">预览</a><td><td></tr> </table> </body> </html>

转载请注明原文地址: https://www.6miu.com/read-39820.html

最新回复(0)