找回密码
 立即注册

QQ登录

只需一步,快速开始

Clark.Pan 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2017-4-17 16:32  /   查看:14051  /  回复:12
众所周知,SpreadJS是前端控件,对后台的语言没有限定。那么SpreadJS是如何与Java后台进行数据交互的呢,让我们来看一下示例:

       本示例完成了一个简单的数据库工具,可以对数据库中所有的表进行增删改查以及导出excel操作。
       其中添加与删除须在完成操作后点击保存按钮,支持批量添加与删除。
       修改数据在操作完成后进行实时更新。
       导出excel使用SpreadJS的前端导出,目前仅支持xlsx格式。



首先,进行环境准备工作:
一,搭建mysql数据库:

mysql下载地址:https://dev.mysql.com/downloads/mysql/

mysql安装步骤:

1.解压安装包

2.配置环境变量

3.修改安装包中的my-default.ini文件
basedir=(mysql所在目录)
datadir=(mysql所在目录\data)

4.这里要说一下,在mysql5.7.6版本之后zip包中不再包括data目录,需要做一下初始化。以下是官网文档原文:
As of MySQL 5.7.6, the Zip Archive no longer includes a data directory. To initialize a MySQL installation by creating the data directory and populating the tables in the mysql system database, initialize MySQL using either --initialize or --initialize-insecure. For additional information, see Section 2.10.1.1, “Initializing the Data Directory Using mysqld”.
所以如果没有data目录请执行以下操作:
       将my-default.ini copy至bin目录下,然后执行:mysqld --initialize 会生成一个随机密码,记下来。


5.以管理员身份运行cmd,进入解压目录的bin目录下输入:mysqld -install,看到service successfully installed的提示表明安装成功。

6.输入:net start mysql启动mysql服务,得到服务启动成功的提示表明,服务已经启动。

7.接下来修改root密码的操作,原始密码为之前生成的随机密码

二,安装JDK,JRE
安装步骤可以参考:http://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html



三,搭建JavaWEB工程,本示例使用maven来构建管理工程。

安装步骤可以参考:http://jingyan.baidu.com/article/295430f136e8e00c7e0050b9.html

四,搭建springmvc框架

1.在maven中配置springmvc的相关依赖jar包
以下为本示例的配置的部分代码可供参考:pom.xml:

  1. <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">
  2.   <modelVersion>4.0.0</modelVersion>
  3.   <groupId>com.spreadjs</groupId>
  4.   <artifactId>demo</artifactId>
  5.   <version>0.0.1-SNAPSHOT</version>
  6.   <packaging>war</packaging>
  7.   <dependencies>
  8.           <dependency>
  9.                   <groupId>mysql</groupId>
  10.                   <artifactId>mysql-connector-java</artifactId>
  11.                   <version>5.1.39</version>
  12.           </dependency>
  13.           <dependency>
  14.             <groupId>javax.servlet</groupId>
  15.             <artifactId>servlet-api</artifactId>
  16.             <version>2.5</version>
  17.             <scope>provided</scope>
  18.         </dependency>
  19.           <dependency>
  20.             <groupId>org.springframework</groupId>
  21.             <artifactId>spring-webmvc</artifactId>
  22.             <version>4.3.7.RELEASE</version>
  23.         </dependency>
  24.         <dependency>
  25.             <groupId>javax.servlet</groupId>
  26.             <artifactId>jstl</artifactId>
  27.             <version>1.2</version>
  28.         </dependency>
  29.         
  30.         <dependency>
  31.                 <groupId>com.fasterxml.jackson.core</groupId>
  32.                 <artifactId>jackson-core</artifactId>
  33.                 <version>2.6.1</version>
  34.         </dependency>
  35.         <dependency>
  36.                 <groupId>com.fasterxml.jackson.core</groupId>
  37.                 <artifactId>jackson-databind</artifactId>
  38.                 <version>2.6.1</version>
  39.         </dependency>
  40.         <dependency>
  41.                 <groupId>com.fasterxml.jackson.core</groupId>
  42.                 <artifactId>jackson-annotations</artifactId>
  43.                 <version>2.6.1</version>
  44.         </dependency>
  45.         <dependency>
  46.                 <groupId>org.codehaus.jackson</groupId>
  47.                 <artifactId>jackson-mapper-asl</artifactId>
  48.                 <version>1.9.13</version>
  49.         </dependency>
  50.         <dependency>
  51.                 <groupId>org.json</groupId>
  52.                 <artifactId>json</artifactId>
  53.                 <version>20140107</version>
  54.         </dependency>
  55.   </dependencies>
  56. </project>
复制代码

2.配置web.xml文件
web.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  3.         <display-name>SpreadJS_Demo</display-name>
  4.           <filter>
  5.             <filter-name>encodingFilter</filter-name>
  6.             <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  7.             <init-param>
  8.                       <param-name>encoding</param-name>
  9.                       <param-value>UTF-8</param-value>
  10.                     </init-param>
  11.           </filter>
  12.           <filter-mapping>
  13.             <filter-name>encodingFilter</filter-name>
  14.             <url-pattern>/*</url-pattern>
  15.          </filter-mapping>
  16.           <servlet>
  17.             <servlet-name>dispatcher</servlet-name>
  18.             <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  19.             <init-param>
  20.                       <param-name>contextConfigLocation</param-name>
  21.                       <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
  22.             </init-param>
  23.             <load-on-startup>1</load-on-startup>
  24.           </servlet>
  25.           <servlet-mapping>
  26.             <servlet-name>dispatcher</servlet-name>
  27.             <url-pattern>/</url-pattern>
  28.           </servlet-mapping>
  29.           <servlet-mapping>
  30.                   <servlet-name>default</servlet-name>  
  31.                   <url-pattern>*.css</url-pattern>  
  32.         </servlet-mapping>  
  33.         <servlet-mapping>  
  34.                 <servlet-name>default</servlet-name>  
  35.                 <url-pattern>*.gif</url-pattern>  
  36.         </servlet-mapping>  
  37.         <servlet-mapping>  
  38.                 <servlet-name>default</servlet-name>  
  39.                 <url-pattern>*.jpg</url-pattern>  
  40.         </servlet-mapping>  
  41.         <servlet-mapping>  
  42.                 <servlet-name>default</servlet-name>  
  43.                 <url-pattern>*.js</url-pattern>  
  44.         </servlet-mapping>  
  45.         <servlet-mapping>  
  46.                 <servlet-name>default</servlet-name>  
  47.                 <url-pattern>*.png</url-pattern>  
  48.         </servlet-mapping>
  49.         <welcome-file-list>
  50.                 <welcome-file>index.jsp</welcome-file>
  51.         </welcome-file-list>
  52. </web-app>
复制代码
3.配置dispatcher-servlet.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xmlns:context="http://www.springframework.org/schema/context"
  5.     xmlns:mvc="http://www.springframework.org/schema/mvc"
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
  8.         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">     
  9.         
  10.         <context:component-scan base-package="com.spreadjs.*"></context:component-scan>
  11.         <mvc:annotation-driven>
  12.                 <mvc:message-converters>
  13.                         <bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
  14.                         <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
  15.                 </mvc:message-converters>
  16.         </mvc:annotation-driven>
  17.         
  18.         <mvc:default-servlet-handler/>
  19.         
  20.         <context:property-placeholder location="classpath:resources.properties" ignore-unresolvable="true"/>
  21.         
  22.         <mvc:resources location="/resources/" mapping="/resources/**" />
  23.         
  24.         <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  25.             <property name="prefix" value="/WEB-INF/views/"></property>
  26.             <property name="suffix" value = ".jsp"></property>
  27.         </bean>
  28. </beans>
复制代码


到此,环境准备工作已经基本完成。接下来,是数据库交互部分的代码编写,本示例采用的是基本的JDBC技术来与mysql数据库进行交互。
一,创建负责创建,关闭数据库连接的工具类DataBaseManager
以下是核心代码:
  1. public Connection getConnection() throws IOException{
  2.                 InputStream in = this.getClass().getClassLoader().getResourceAsStream("resources.properties");
  3.                 Properties ps = new Properties();
  4.                 ps.load(in);
  5.                 in.close();
  6.                 String url = ps.get("url").toString();
  7.                 String name = ps.get("name").toString();
  8.                 String user = ps.get("user").toString();
  9.                 String password = ps.get("password").toString();
  10.                 Connection conn = null;
  11.                 try {
  12.                         Class.forName(name);
  13.                         conn = DriverManager.getConnection(url, user, password);
  14.                 } catch (Exception e) {
  15.                         e.printStackTrace();
  16.                 }
  17.                 return conn;
  18.         }
复制代码
本代码用户创建mysql的数据库连接connection。
二,根据业务逻辑编写业务逻辑层。
附一个查询逻辑的代码,其余代码可以见上传附件。
  1. public Map<String,Object> getDataFromTableName(String tableName) throws Exception{
  2.                 Map<String,Object> dataMap = new HashMap<String,Object>();
  3.                 List<Map<String,Object>> listMap = new ArrayList<Map<String,Object>>();
  4.                 String sql = "select * from "+tableName;
  5.                 Connection conn = null;
  6.                 PreparedStatement pstmt = null;
  7.                 ResultSet rs = null;
  8.                 try {
  9.                         conn = new DataBaseManager().getConnection();
  10.                         pstmt = conn.prepareStatement(sql);
  11.                         rs = pstmt.executeQuery();
  12.                         ResultSetMetaData rsmd = rs.getMetaData();
  13.                         List<Map<String,Object>> columns = new ArrayList<Map<String,Object>>();
  14.                         for(int i=1;i<=rsmd.getColumnCount();i++){
  15.                                 Map<String,Object> columnPerferences = new HashMap<String,Object>();
  16.                                 columnPerferences.put("columnName", rsmd.getColumnName(i));
  17.                                 columnPerferences.put("columnType", rsmd.getColumnType(i));
  18.                                 columns.add(columnPerferences);
  19.                         }
  20.                         dataMap.put("columnSetting", columns);
  21.                         while(rs.next()){
  22.                                 Map<String,Object> resultMap = new LinkedHashMap<String,Object>();
  23.                                 for(int j=0;j<columns.size();j++){
  24.                                         int columnType = Integer.parseInt(columns.get(j).get("columnType").toString());
  25.                                         String columnName = columns.get(j).get("columnName").toString();
  26.                                         if (Types.VARCHAR == columnType) {
  27.                                                 resultMap.put(columnName, rs.getObject(columnName)==null?null:rs.getString(columnName));
  28.                                         } else if (Types.INTEGER == columnType) {
  29.                                                 resultMap.put(columnName, rs.getObject(columnName)==null?null:rs.getInt(columnName));
  30.                                         } else if (Types.SMALLINT == columnType) {
  31.                                                 resultMap.put(columnName, rs.getObject(columnName)==null?null:rs.getShort(columnName));
  32.                                         } else {
  33.                                                 resultMap.put(columnName, rs.getObject(columnName)==null?null:rs.getString(columnName));
  34.                                         }
  35.                                 }
  36.                                 listMap.add(resultMap);
  37.                         }
  38.                         dataMap.put("dataList", listMap);
  39.                 } catch (SQLException e) {
  40.                         throw new Exception(e.getMessage());
  41.                 } finally {
  42.                         new DataBaseManager().closeConnection(conn);
  43.                         new DataBaseManager().closePstmt(pstmt);
  44.                 }
  45.                 return dataMap;
  46.         }
复制代码

该方法可以根据表名查出表中的所有字段以及各个字段的值,将其返回成指定的数据结构,便于和前端进行交互。

三,编写前端,运用SpreadJS将数据源展现出来。
附一个查询逻辑的前端代码逻辑,其余代码可以见上传附件。
  1. var selectedTableName = $("#table_name").find("option:selected").text();
  2.         $.ajax({
  3.                 url: "getDataFromTableName",
  4.                 type:"post",
  5.                 data:{tableName:selectedTableName},
  6.                 datatype: "json",
  7.                 success: function (data) {
  8.                         //var json = JSON.parse(data);
  9.                         if(data.isSuccess == 1){
  10.                                 spread.suspendPaint();
  11.                                 sheet.clearPendingChanges();
  12.                                 columnSetting = data.resultData.columnSetting;
  13.                                 sheet.setDataSource(data.resultData.dataList);
  14.                                 formatColumn(columnSetting);
  15.                                 spread.resumePaint();
  16.                         }else{
  17.                                 alert(data.errorMessage);
  18.                         }
  19.                 },
  20.                 error: function (ex) {
  21.                         alert(ex);
  22.                 }
  23.         });
复制代码
可以看到使用ajax技术向后台发送请求,在将请求返回的结果,用SpreadJS内置的setDataSource()方法来将数据显示出来。


以上只是其中一个简单的业务逻辑,具体详细的逻辑以及实现方式请参看附件代码。

接下来就是将代码部署到服务器上,本示例使用tomcat作为发布服务器。
tomcat的安装与环境配置可以参考:http://jingyan.baidu.com/article/8065f87fcc0f182330249841.html

SpreadJS_Demo.zip

1.23 MB, 阅读权限: 1, 下载次数: 1155

12 个回复

倒序浏览
UncleYiba
注册会员   /  发表于:2017-5-11 06:23:55
沙发
请问部署到tomcat,并启动之后如何在浏览器中打开,我打开连接“http://localhost:8080/index”报404
回复 使用道具 举报
UncleYiba
注册会员   /  发表于:2017-5-11 07:34:54
板凳
之前的问题自己搞定了,用了一下demo,是一个数据库中有几张表就能展示出来的一个demo。
主要想实现的功能是excel的上传,在线填写和导出。
在线填写demo中有,导出功能demo中也有,应该只是一种粗略的导出。
想知道上传的有各种样式的excel会以什么样的形式保存到数据库中
回复 使用道具 举报
Clark.Pan讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2017-5-11 09:18:46
地板
UncleYiba 发表于 2017-5-11 07:34
之前的问题自己搞定了,用了一下demo,是一个数据库中有几张表就能展示出来的一个demo。
主要想实现的功 ...

这个demo本来是为了将数据库中的表信息在spreadjs中显示出来并且可以进行基本操作,类似数据库工具的功能。如果是您这种情况,需要将EXCEL内容保存至数据库,可以导入Excel以后导出成json字符串然后将json字符串存入数据库。这样,下次从数据库载入时直接用spreadjs导入json字符串即可,这样不仅能够保存数据也可以保存样式。
spread json的导入导出可以参考:http://demo.gcpowertools.com.cn/ ... preadFromJSONtoJSON
Excel的导入导出可以参考:
http://demo.gcpowertools.com.cn/ ... e/#/samples/ExcelIO
回复 使用道具 举报
UncleYiba
注册会员   /  发表于:2017-5-11 10:08:44
5#
ClarkPan 发表于 2017-5-11 09:18
这个demo本来是为了将数据库中的表信息在spreadjs中显示出来并且可以进行基本操作,类似数据库工具的功能 ...

样式和数据希望区分下来,数据依旧以之前的那种demo的形式保存在数据库中,因为后续要对表中的数据做一些汇总处理之类的工作。
样式可以作为一张空表序列化成一个字符串,那怎么和该表填写的数据匹配起来。
实际需求就是:
A上传了一张表a的样式(空表);
B在线填写这张表a的数据,或者导出之后填写完数据,上传直接填完的表格,系统会自动得到填写的数据并保存在数据库中;
C同B一样,但是相互独立,也是填写或上传数据
当然也可以有DEF进行数据的填写操作
最后A可以得到表a,里面的数据时所有人填写的数据汇总。
就是样式和数据时分开操作的
回复 使用道具 举报
Clark.Pan讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2017-5-11 10:33:15
6#
UncleYiba 发表于 2017-5-11 10:08
样式和数据希望区分下来,数据依旧以之前的那种demo的形式保存在数据库中,因为后续要对表中的数据做一些 ...

样式是所有表都一样还是会根据表中数据不同来变化
回复 使用道具 举报
UncleYiba
注册会员   /  发表于:2017-5-11 10:36:49
7#
ClarkPan 发表于 2017-5-11 10:33
样式是所有表都一样还是会根据表中数据不同来变化

样式就是有一个大的表头啊,结尾有备注啊之类的,就相当于一个框子,然后在里面填写数据,BCD等等要填写的表都是同一张样式表,他们的数据相互独立,只有A可以查看所有数据
回复 使用道具 举报
Clark.Pan讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2017-5-11 10:40:36
8#
UncleYiba 发表于 2017-5-11 10:36
样式就是有一个大的表头啊,结尾有备注啊之类的,就相当于一个框子,然后在里面填写数据,BCD等等要填写 ...

那可以在初始化的时候将样式用代码绘制就行,无需存入数据库中
回复 使用道具 举报
UncleYiba
注册会员   /  发表于:2017-5-11 10:44:40
9#
ClarkPan 发表于 2017-5-11 10:40
那可以在初始化的时候将样式用代码绘制就行,无需存入数据库中

样式就是A最初上传的空表。

A上传表模板
BCDE在A的模板上填写数据,相互填写内容不可见
A查看所有人填写的数据

样式是根据上传的表自动生成的,可以当做一个空表看
回复 使用道具 举报
Clark.Pan讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2017-5-11 11:04:11
10#
UncleYiba 发表于 2017-5-11 10:44
样式就是A最初上传的空表。

A上传表模板

这个是需要在数据库以及查询语句上做处理的,跟spreadjs已经没有多大关系了,举个例子:在表A中加入一个字段type 表A中的查询语句是全查,没有where条件的,表B中的是where='B'的以此类推,处理填完新增是将type='x'带上,就可以了。数据显示时不显示type这一列就行了。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部