这里我用的是官方给的数据库,即编辑页面,是一个简单的demo,没有签章等功能,这个控件是需要购买的,不购买的话有试用版,但虽然可以用,但保存会有有使用字样的图片,而且外面的框上也会有使用字样。
网上没有相关使用资料及介绍,能找到的只有demo和API文档,所以写下这篇,给后面的人提供个思路。
1、将下载的试用版控件解压,
2、把jar包添加到本地仓库,方便后面我们用pom的方式
mvn install:install-file -DgroupId=com.sunnada.gaia -DartifactId=eWebOffice -Dversion=0.1 -Dpackaging=jar -Dfile=E:/eWebOfficeServer.jar
3、把它的eWebOffice这个文件全部复制到resources的static下,SpringBoot默认读取,还有jquery,
4、配置application.properties
这里我们将eWebOffice的授权码放到配置文件里。
# orcle
spring.datasource.url=jdbc:oracle:thin:@******:orcl
spring.datasource.username= ***
spring.datasource.password= ***
spring.datasource.driverClassName = oracle.jdbc.OracleDriver
# 旧版的Oracle JDBC Driver Class :oracle.jdbc.driver.OracleDriver
# 新版的Oracle JDBC Driver Class :oracle.jdbc.OracleDriver
spring.datasource.hikari.maximum-pool-size=5
#缓存
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/page/
spring.thymeleaf.check-template-location=true
#调试日志打印
logging.level.com.sunnada.gaia.task.dao=DEBUG
#eWebOffice授权码
eWebOfficeLicense=***
5、pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sunnada.task</groupId>
<artifactId>task-page</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mybatis-spring-boot-starte.version>1.3.2</mybatis-spring-boot-starte.version>
<pageoffice-version>4.5.0.6</pageoffice-version>
<eWebOffice-version>0.1</eWebOffice-version>
<oracle-version>12.2.0.1</oracle-version>
<er-ri-version>1.0</er-ri-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- thymeleaf 页面-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.sunnada</groupId>
<artifactId>eWebOffice</artifactId>
<version>${eWebOffice-version}</version>
</dependency>
<!--Oracle JDBC Driver需要手动安装 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc8</artifactId>
<version>${oracle-version}</version>
</dependency>
<!-- swagger 测试框架-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.7</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot-starte.version}</version>
</dependency>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.1.0.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.2.RELEASE</version>
<scope>test</scope>
</dependency>
<!--jsp相关配置 必须-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.el/el-ri -->
<dependency>
<groupId>com.sun.el</groupId>
<artifactId>el-ri</artifactId>
<version>${er-ri-version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--逆向生成插件配置-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<phase>deploy</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<!--允许移动生成的文件 -->
<verbose>true</verbose>
<!-- 是否覆盖 -->
<overwrite>true</overwrite>
<!-- 自动生成的配置 -->
<configurationFile>
src/main/resources/mybatis-generator.xml
</configurationFile>
</configuration>
</plugin>
</plugins>
</build>
</project>
6、在线编辑页面
我们可以简单的做两个页面,
第一个页面是文件列表,第二个页面是编辑页面
default.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>文档列表</title>
</head>
<body>
<table>
<tr>
<td>名称</td>
<td>操作</td>
</tr>
<th:block th:each="d,in:${dataList}">
<tr>
<td th:text="${d.dFilename}"></td>
<td ><a th:href="@{/edit(ms_Action=norevision,recordId=${d.dRecordid},Action=LOADFILE,fileName=${d.dFilename})}">编辑</a></td>
</tr>
</th:block>
</table>
</body>
</html>
documnet_edit.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.springframework.org/schema/jdbc">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Expires" CONTENT="0">
<meta http-equiv="Cache-Control" CONTENT="no-cache">
<meta http-equiv="Pragma" CONTENT="no-cache">
<title>eWebOffice示例 : 编辑文档</title>
<link rel="stylesheet" type="text/css" href="css/eweboffice.css" />
<script src="jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="eWebOffice/eWebOffice.js"></script>
<script type="text/javascript" for="eWebOffice1" event="OnInit()" th:inline="javascript">
//控件初始化事件
//标题栏、快捷工具栏、边框等界面相关设置可以在此事件中作,使得界面上不会有转变过程显现
//如:隐藏快捷工具栏。当访问此网页时,如在OnLoad中设,则会先显示出工具栏,再看到工具栏没了。如在OnInit中设,直接打开就看不到。没有这个变化过程。
eWebOfficeJS.SetWorkModeOnInit("eWebOffice1", [[${param.ms_Action}]]);
alert();
</script>
<script type="text/javascript" for="eWebOffice1" event="OnDocumentAfterOpen()" th:inline="javascript">
//文档打开后触发此事件
//在此事件中设置初始Office菜单、工具栏、痕迹、保护等。
eWebOfficeJS.SetWorkModeOnOpen("eWebOffice1", [[${param.ms_Action}]]);
</script>
<script type="text/javascript" for="eWebOffice1" event="OnLoad()" th:inline="javascript">
var http = window.location.protocol;//协议
var ip = document.domain;//域名
var port = window.location.port;//端口
eWebOffice1.WebUrl = http+"//"+ip+":"+port+"/loadWord";
// eWebOffice1.WebUrl = "http://127.0.0.1:8080/loadWord";//加载文件的url
// alert("域名;"+document.domain);
// alert("端口:"+window.location.port);
// alert("协议:"+window.location.protocol);
eWebOffice1.RecordID = [[${param.recordId}]];
eWebOffice1.FileName = [[${param.fileName}]];
eWebOffice1.FileType = [[${param.fileType}]];
eWebOffice1.QuickBarVisible=true;//快捷工具栏是否显示
eWebOffice1.QuickBarFileVisible=true;//快捷工具栏下的文件操作相关功能按钮是否显示
eWebOffice1.QuickBarSkin="BLUE1";//设置工具栏皮肤
eWebOffice1.SetRibbonVisible("TabAddIns",false);//隐藏加载项
//本地保存,新建,打开按钮隐藏
eWebOffice1.SetQuickBarItemVisible("SYS_QB_LocalSave",false);//设置指定按钮是否可见
eWebOffice1.SetQuickBarItemVisible("SYS_QB_New",false);
eWebOffice1.SetQuickBarItemVisible("SYS_QB_Open",false);
eWebOffice1.FFSBVisible=false;//右上角的全屏按钮是否显示
eWebOffice1.RefreshQuickBar();//在设置按钮后要刷新才效果,
//使用下载到本地,再打开的方式,使用WebOpen方式会一直提示“无效文档”
// eWebOffice1.WebOpen();//这个方式不行,不能使用;不管是使用Word二进制还是字符串二进制都不能打开
//为保证浏览器不访问相同的url,在最后增加了时间戳
eWebOffice1.WebOpenFromUrl(http+"//"+ip+":"+port+"/getFile?recordId="+[[${param.recordId}]]+"&fileName="+[[${param.fileName}]]+"&timeStamp="+(new Date()).valueOf());
</script>
<script type="text/javascript" for="eWebOffice1" event="OnCustomButtonClick(s_Key, s_Value)">
//s_Key: 为自定义按钮关键字,可以随便定义,不要与系统自带冲突即可,演示中为了区别,快捷工具栏上的按钮定义为"QB_"开头,Office文件菜单下的按钮定义为"File_"开头。
switch(s_Key){
case "QB_ViewThumbnails":
eWebOffice1.WebObject.Application.ActiveWindow.Thumbnails = true;
break;
case "QB_ViewDocumentMap":
eWebOffice1.WebObject.Application.ActiveWindow.DocumentMap = true;
break;
case "QB_ViewPage":
eWebOffice1.WebObject.Application.ActiveWindow.Thumbnails = false;
eWebOffice1.WebObject.Application.ActiveWindow.DocumentMap = false;
break;
case "QB_Print":
eWebOffice1.PrintDialog();
break;
case "QB_WebSave":
eWebOffice1.WebSave();
break;
}
</script>
<script type="text/javascript">
function DoCheckSubmit(){
if (document.getElementById("d_subject").value==""){
alert("主题不能为空!");
return false;
}
if (document.getElementById("d_author").value==""){
alert("作者不能为空!");
return false;
}
try{
// return eWebOffice1.WebSave();
}catch(e){
alert("请选安装eWebOffice控件,再操作!");
return false;
}
}
</script>
</head>
<body>
<div id="bdy">
<div id="nav">您当前位置 >> <a href="default.jsp">eWebOffice示例首页</a> >> 文档编辑[<span class=red><%=ms_NodeDesc %></span>]</div>
<hr />
<form name="form1" method="post" action="/save" onsubmit="return DoCheckSubmit()">
<input type="hidden" name="d_recordid" id="d_recordid" th:value="${recordId}" />
<input type="hidden" name="d_filetype" id="d_filetype" th:value="${fileType}" />
<table class="edit">
<tr>
<td align="center" width="10%">主 题</td>
<td width="40%"><input class="txt" type="text" name="d_subject" id="d_subject" value="测试" size="50" /></td>
<td width="50%" rowspan="2" align="center">
<input type="submit" class="btn4" value="保存文档">
<input type="button" class="btn4" onclick="kk='default.jsp'" value="返回列表">
<span class=red>注意:只有进行“保存文档”后,所做的操作才有效!</span></td>
</tr>
<tr>
<td align="center">作 者</td>
<td><input class="txt" type="text" name="d_author" id="d_author" value="测试" size="50" /></td>
</tr>
</table>
</form>
<!--创建eWebOffice实例-->
<script type="text/javascript">
eWebOfficeJS.Create("eWebOffice1", "100%", "700px");
</script>
<hr />
<div id="footer">Copyright © <span style="color:Blue;">eWebSoft.com</span>, All Rights Reserved . 福州极限软件开发有限公司 邮箱:<a href="mailto:service@ewebsoft.com">service@ewebsoft.com</a> 官网:<a href="http://www.ewebsoft.com/eweboffice/" target="_blank">http://www.ewebsoft.com/eweboffice/</a></div>
</div>
</body>
</html>
重点代码是OnLoad()方法里的,文件打开的url、参数获取、及操作按钮工具栏设置等都在里面。
我的理解是这样的,控件本身也是有异步操作的。当我们在接收到第一个页面default.html的请求时,获取到各种参数,并在Init方法里初始化工具栏,我们也可以在Onload方法里设置,但是在Init方法里设置的,在页面显示到我们看到到最终都不会发生变化,但是在OnLoad方法里设置的,如果和Init方法里的不一样,本身加载文件也不会很快,所以按钮变化很明显。
在打开Word后,窗口的左上角有一个“全屏显示”的按钮,所以,我们可以把右上角的那个“全屏”按钮给隐藏,eWebOffice1.FFSBVisible=false;//右上角的全屏按钮是否显示
最后记得在所有设置完后调用:eWebOffice1.RefreshQuickBar();//在设置按钮后要刷新才效果,
才有效果。
7、然后是按钮设置。
按照自己的需求修改就可以了。
有一点我要提一下,就是js里的switch是严格比较,等价于“===”所有,我们在传入参数给s_WorkModeFlag时,我们知道是字符串,但是我们要明确他的类型,所以
8、页面基本设置完了,开始后台设置。
首先创建一个controller
package com.sunnada.gaia.task.controller;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sunnada.gaia.task.model.DocumentFile;
import com.sunnada.gaia.task.service.DocumentFileService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* eweboffice在线文档编辑
*
* @author 李瑞益
*/
@Controller
public class EwebOfficeTestController {
@Resource
private DocumentFileService documentFileService;
/**
* 默认页面
* @param model
* @return
*/
@GetMapping("/index")
public String index(Model model){
List<DocumentFile> all = documentFileService.getAll();
model.addAttribute("dataList",all);
return "default";
}
/**
* 跳转到编辑页面
* @param request
* @param response
* @return
*/
@GetMapping("/edit")
public String edit( HttpServletRequest request,HttpServletResponse response)
{
return "document_edit";
}
/**
* 使用下载本地打开的方式
* @param recordId
* @param fileName
* @param response
*/
@RequestMapping("/getFile")
public void getFile(String recordId,String fileName,HttpServletResponse response){
DocumentFile model = documentFileService.getByRecordId(recordId);
response.setContentType("ms-word");
response.setHeader("Content-Disposition", "attachment;filename="+fileName);
OutputStream os = null;
try {
os = response.getOutputStream();
os.write(model.getdFilebody());
os.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(os != null)
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
然后是servlet;为什么我们要用servlet我在这里讲一下:
控件有一个方法WebMsgLoad(PageContext),我们后续那些获取参数设置参数都是以这个为前提。而这个PageContext是jsp的内置对象,所以我们只能构造他
package com.sunnada.gaia.task.controller;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ewebsoft.eweboffice.eWebOfficeServer;
import com.sunnada.gaia.task.model.DocumentFile;
import com.sunnada.gaia.task.service.DocumentFileService;
import com.sunnada.gaia.task.util.EWebOfficeUtil;
/**
*
*
* @author 李瑞益
*/
@WebServlet(urlPatterns = "/loadWord")
public class LoadFileServelt extends HttpServlet {
/**
* eWebOffice的授权码
*/
@Value("${eWebOfficeLicense}")
private String license;
@Resource
private DocumentFileService documentFileService;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
eWebOfficeServer wos = new eWebOfficeServer();
wos.SetLicense(license);
//加载数据
if (!wos.WebMsgLoad(getPageContext(this,req,resp))) {
return;
}
//获取到前端的操作符,进行操作判断
//判断什么操作
String s_action = wos.WebMsgGetString("Action");
//加载数据我们不在这里做,
if (s_action.equals("SAVEFILE")) {
//保存文件
save(wos);
}
}
//
// /**
// * 该方法弃用
// * @param wos
// */
// public void loadFile(eWebOfficeServer wos,String recordId){
// DocumentFile model = documentFileService.getByRecordId(recordId);
// //设置文档名和类型
// if(model.getdFiletype() != null)
// wos.WebMsgSetString("fileType",model.getdFiletype());
// //设置文档数据
// wos.WebMsgSetStream("fileBoby",model.getdFilebody());
// //加载文件
wos.WebMsgSetFile("word","C:\\Users\\LI\\Desktop\\test5.doc");
write(model.getdFilebody());
// //文档加载状态
// wos.WebMsgStatus("TRUE", "文件加载成功!");
// //将服务端数据发送到前端
// wos.WebMsgSend();
// }
public void save(eWebOfficeServer wos){
String s_RecordID = wos.WebMsgGetString("RecordID");
byte[] a_FileBody = wos.WebMsgGetStream("FileBody");
wos.WebMsgClear();
DocumentFile documentFile = documentFileService.getByRecordId(s_RecordID);
documentFile.setdFilebody(a_FileBody);
int update = documentFileService.update(documentFile);
//测试写入
// testWrite(documentFileService.getByRecordId(s_RecordID).getdFilebody());
if (update > 0) {
wos.WebMsgStatus("true","保存成功");
}
}
/**
* 获取servlet的PageContext对象
* @param servlet servlet对象
* @param request 请求
* @param response 响应
* @return
*/
public PageContext getPageContext(Servlet servlet,HttpServletRequest request,HttpServletResponse response){
return JspFactory.getDefaultFactory().getPageContext(servlet,request,response,null,true,8192,true);
}
public void testWrite(byte[] data){
OutputStream os = null;
try {
os = new FileOutputStream("C:\\Users\\LI\\Desktop\\changeWord.doc");
os.write(data);
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if(os != null)
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最后不要忘了在主程序中加上servlet扫描
@SpringBootApplication
@MapperScan("com.sunnada.gaia.task.dao")
@ServletComponentScan("com.sunnada.gaia.task.controller")
public class Appliaction {
public static void main(String[] args){
SpringApplication.run(Appliaction.class);
}
}
至此,简单的在线编辑结束。