Spring3MVC 导入导出excel

本教程我们将通过Apache的 POI进行excel的导出和写入:
即把数据库的数据导出excel格式,
读取excel表报中的数据并写入数据库.

我们将会使用mysql进行数据的操作.

POI是什么?

引用
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能。 .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 POI 的功能。


也可以访问 Apache POI 官方网站

目前最新版本为3.8b2,此教程我们将采用3.7版本.

对于POI的基本用法可以观看官方的 quick-guide

下面是我们的应用程序文件夹结构:



然后是pom.xml里添加的jar包:



注意:poi的jar包一定要导入poi-ooxml
通过依赖顺便能导入poi.
如果直接导入poi后面的WebbookFactory将找不到jar包.

在数据库spring3db中创建一个表 computer
Mysql代码   收藏代码
  1. CREATE TABLE `computer` (  
  2.   `ID` BIGINT(20) NOT NULL AUTO_INCREMENT,  
  3.   `BRAND` VARCHAR(255) DEFAULT NULL,  
  4.   `CPU` VARCHAR(255) DEFAULT NULL,  
  5.   `GPU` VARCHAR(255) DEFAULT NULL,  
  6.   `MEMORY` VARCHAR(255) DEFAULT NULL,  
  7.   `PRICE` DOUBLE DEFAULT NULL,  
  8.   PRIMARY KEY (`ID`)  
  9. ) ENGINE=INNODB AUTO_INCREMENT=67 DEFAULT CHARSET=utf8  


也可以直接把附件代码中src/main/resource/data下面的spring3db.sql导入数据库中.
导入后的数据库如下所示




首先添加Spring MVC所必须的配置.

web.xml

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app id="WebApp_ID" version="2.4"  
  3.     xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
  5.     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  6.   
  7.     <welcome-file>index.jsp</welcome-file>  
  8.   
  9.     <context-param>  
  10.         <param-name>contextConfigLocation</param-name>  
  11.         <param-value>  
  12.         /WEB-INF/application-dataSource.xml  
  13.         /WEB-INF/applicationContext.xml  
  14.         </param-value>  
  15.     </context-param>  
  16.   
  17.     <servlet>  
  18.         <servlet-name>spring</servlet-name>  
  19.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  20.         <load-on-startup>1</load-on-startup>  
  21.     </servlet>  
  22.   
  23.     <servlet-mapping>  
  24.         <servlet-name>spring</servlet-name>  
  25.         <url-pattern>/</url-pattern>  
  26.     </servlet-mapping>  
  27.   
  28.     <listener>  
  29.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  30.     </listener>  
  31.   
  32.   
  33. </web-app>  


在web.xml中我们定义servlet:spring.
按照惯例,我们必须声明一个spring-servle.xml

spring-servle.xml

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" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  6.   
  7.     <!-- 定义一个视图解析器 -->  
  8.     <bean id="viewResolver"  
  9.         class="org.springframework.web.servlet.view.InternalResourceViewResolver"  
  10.         p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />  
  11.   
  12.     <!-- Spring分段文件上传所必须的 ,用于检查请求中是否包含multipart  
  13.     see: http://www.html.org.cn/books/springReference/ch13s08.html  
  14.     -->  
  15.     <bean id="multipartResolver"  
  16.         class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:maxUploadSize="5000000"  
  17.      />  
  18.           
  19. </beans>  


这个XML配置声明一个视图解析器.在控制器中会根据JSP名映射到/ WEB-INF/jsp中相应的位置.
spring-servle.xml中的multipartResolver是Spring分段文件上传所必须的 ,用于检查请求中是否包含multipart.
更多的详情 对分段文件上传(multipart file upload)的支持

要进行数据库操作,一定需要一个数据库连接的配置.

jdbc.properties
Properties代码   收藏代码
  1. # database properties  
  2. #spring3db is databaseName.  
  3. app.jdbc.driverClassName=com.mysql.jdbc.Driver  
  4. app.jdbc.url=jdbc:mysql://localhost/spring3db  
  5. app.jdbc.username=root  
  6. app.jdbc.password=root  



application-dataSource.xml

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:p="http://www.springframework.org/schema/p"   
  6.     xmlns:tx="http://www.springframework.org/schema/tx"  
  7.     xsi:schemaLocation="  
  8.         http://www.springframework.org/schema/beans   
  9.         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  10.         http://www.springframework.org/schema/context   
  11.         http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  12.         http://www.springframework.org/schema/tx   
  13.         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">  
  14.   
  15.     <description>dataSource配置</description>  
  16.   
  17.     <!-- 指定数据库配置文件地址. -->  
  18.     <context:property-placeholder location="classpath*:/jdbc.properties"/>  
  19.       
  20.      <!-- 启用注释管理事务注释风格. -->  
  21.     <tx:annotation-driven transaction-manager="transactionManager"/>  
  22.   
  23.     <!--声明一个数据源.c3p0-->  
  24.     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
  25.         destroy-method="close"  
  26.         p:driverClass="${app.jdbc.driverClassName}"  
  27.         p:jdbcUrl="${app.jdbc.url}"  
  28.         p:user="${app.jdbc.username}"  
  29.         p:password="${app.jdbc.password}"  
  30.         p:acquireIncrement="5"  
  31.         p:idleConnectionTestPeriod="60"  
  32.         p:maxPoolSize="100"  
  33.         p:maxStatements="50"  
  34.         p:minPoolSize="10"   
  35.         p:maxIdleTime="25000"  
  36.     />  
  37.       
  38.     <!--声明一个事务管理器. -->  
  39.     <bean id="transactionManager"  
  40.     class="org.springframework.jdbc.datasource.DataSourceTransactionManager"  
  41.     p:dataSource-ref="dataSource" />  
  42.       
  43.   
  44. </beans>  


该文件主要配置了:
1.启用了事务管理
2.声明了一个数据源

然后创建一个applicationContext.xml.

applicationContext.xml.

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   
  7.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.             http://www.springframework.org/schema/context  
  9.             http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  10.             http://www.springframework.org/schema/mvc   
  11.             http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  12.   
  13.     <!-- 激活spring的注解. -->  
  14.     <context:annotation-config />  
  15.   
  16.     <!-- 扫描注解组件并且自动的注入spring beans中.   
  17.     例如,他会扫描@Controller 和@Service下的文件.所以确保此base-package设置正确. -->  
  18.     <context:component-scan base-package="org.liukai.tutorial" />  
  19.   
  20.     <!-- 配置注解驱动的Spring MVC Controller 的编程模型.注:此标签只在 Servlet MVC工作! -->  
  21.     <mvc:annotation-driven />  
  22.       
  23. </beans>  


至此,基本的配置文件就完成了.

然后我们定义一个Computer对象

Computer.java
Java代码   收藏代码
  1. package org.liukai.tutorial.domain;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Computer implements Serializable {  
  6.   
  7.     private static final long serialVersionUID = 7955753961332480136L;  
  8.   
  9.     private Long id;  
  10.     private String brand;  
  11.     private String cpu;  
  12.     private String gpu;  
  13.     private String memory;  
  14.     private Double price;  
  15.   
  16.     //getter&setter  
  17.   
  18. }  



接下来就是POI来操作excel了.

需要注意的是POI里每个不同的模块代表了对不同格式档案的操作.如下:

 
引用
 
    HSSF - 提供读写Microsoft Excel XLS格式档案的功能。
    XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。
    HWPF - 提供读写Microsoft Word DOC格式档案的功能。
    HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
    HDGF - 提供读Microsoft Visio格式档案的功能。
    HPBF - 提供读Microsoft Publisher格式档案的功能。
    HSMF - 提供读Microsoft Outlook格式档案的功能。


在本教程中我们是实现对excel的操作.所以包含了HSSF和XLSX(开头在pom导入中强调了需要
导入ooxml的jar包,也包含了XSSF)

对导出的excel进行自定义格式:

Layouter.java
Java代码   收藏代码
  1. package org.liukai.tutorial.poi;  
  2.   
  3.   
  4. import org.apache.poi.hssf.usermodel.HSSFCell;  
  5. import org.apache.poi.hssf.usermodel.HSSFCellStyle;  
  6. import org.apache.poi.hssf.usermodel.HSSFRow;  
  7. import org.apache.poi.hssf.usermodel.HSSFSheet;  
  8. import org.apache.poi.hssf.util.CellRangeAddress;  
  9. import org.apache.poi.hssf.util.HSSFColor;  
  10. import org.apache.poi.ss.usermodel.CellStyle;  
  11. import org.apache.poi.ss.usermodel.Font;  
  12. import org.liukai.tutorial.utils.DateUtils;  
  13.   
  14. /** 
  15.  * 更多单元格请查看http://justdoblogger.com/blog/200911/setfillforegroundcolor.html 
  16.  *  
  17.  * @author liukai 
  18.  *  
  19.  */  
  20. @SuppressWarnings("deprecation")  
  21. public class Layouter {  
  22.   
  23.     /** 
  24.      * 创建报表 
  25.      */  
  26.     public static void buildReport(HSSFSheet worksheet, int startRowIndex,  
  27.             int startColIndex) {  
  28.         // 设置列的宽度  
  29.         worksheet.setColumnWidth(05000);  
  30.         worksheet.setColumnWidth(15000);  
  31.         worksheet.setColumnWidth(25000);  
  32.         worksheet.setColumnWidth(35000);  
  33.         worksheet.setColumnWidth(45000);  
  34.         worksheet.setColumnWidth(55000);  
  35.   
  36.         buildTitle(worksheet, startRowIndex, startColIndex);  
  37.   
  38.         buildHeaders(worksheet, startRowIndex, startColIndex);  
  39.   
  40.     }  
  41.   
  42.     /** 
  43.      * 创建报表标题和日期 
  44.      */  
  45.     private static void buildTitle(HSSFSheet worksheet, int startRowIndex,  
  46.             int startColIndex) {  
  47.         // 设置报表标题字体  
  48.         Font fontTitle = worksheet.getWorkbook().createFont();  
  49.         fontTitle.setBoldweight(Font.BOLDWEIGHT_BOLD);  
  50.         fontTitle.setFontHeight((short280);  
  51.   
  52.         // 标题单元格样式  
  53.         HSSFCellStyle cellStyleTitle = worksheet.getWorkbook()  
  54.                 .createCellStyle();  
  55.         cellStyleTitle.setAlignment(CellStyle.ALIGN_CENTER);  
  56.         cellStyleTitle.setWrapText(true);  
  57.         cellStyleTitle.setFont(fontTitle);  
  58.   
  59.         // 报表标题  
  60.         HSSFRow rowTitle = worksheet.createRow((short) startRowIndex);  
  61.         rowTitle.setHeight((short500);  
  62.         HSSFCell cellTitle = rowTitle.createCell(startColIndex);  
  63.         cellTitle.setCellValue("Computer Report!");  
  64.         cellTitle.setCellStyle(cellStyleTitle);  
  65.   
  66.         // 合并区域内的报告标题  
  67.         worksheet.addMergedRegion(new CellRangeAddress(0005));  
  68.   
  69.         // date header  
  70.         HSSFRow dateTitle = worksheet.createRow((short) startRowIndex + 1);  
  71.         HSSFCell cellDate = dateTitle.createCell(startColIndex);  
  72.         cellDate.setCellValue("这个报表创建于: " + DateUtils.getNowTime());  
  73.     }  
  74.   
  75.     /** 
  76.      * 创建表头 
  77.      */  
  78.     private static void buildHeaders(HSSFSheet worksheet, int startRowIndex,  
  79.             int startColIndex) {  
  80.         // Header字体  
  81.         Font font = worksheet.getWorkbook().createFont();  
  82.         font.setBoldweight(Font.BOLDWEIGHT_BOLD);  
  83.   
  84.         // 单元格样式  
  85.         HSSFCellStyle headerCellStyle = worksheet.getWorkbook()  
  86.                 .createCellStyle();  
  87.         headerCellStyle.setFillBackgroundColor(HSSFColor.GREY_25_PERCENT.index);  
  88.         headerCellStyle.setFillPattern(CellStyle.FINE_DOTS);  
  89.         headerCellStyle.setAlignment(CellStyle.ALIGN_CENTER);  
  90.         headerCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);  
  91.         headerCellStyle.setWrapText(true);  
  92.         headerCellStyle.setFont(font);  
  93.         headerCellStyle.setBorderBottom(CellStyle.BORDER_THIN);  
  94.   
  95.         // 创建字段标题  
  96.         HSSFRow rowHeader = worksheet.createRow((short) startRowIndex + 2);  
  97.         rowHeader.setHeight((short500);  
  98.   
  99.         HSSFCell cell1 = rowHeader.createCell(startColIndex + 0);  
  100.         cell1.setCellValue("Id");  
  101.         cell1.setCellStyle(headerCellStyle);  
  102.   
  103.         HSSFCell cell2 = rowHeader.createCell(startColIndex + 1);  
  104.         cell2.setCellValue("Brand");  
  105.         cell2.setCellStyle(headerCellStyle);  
  106.   
  107.         HSSFCell cell3 = rowHeader.createCell(startColIndex + 2);  
  108.         cell3.setCellValue("CPU");  
  109.         cell3.setCellStyle(headerCellStyle);  
  110.   
  111.         HSSFCell cell4 = rowHeader.createCell(startColIndex + 3);  
  112.         cell4.setCellValue("GPU");  
  113.         cell4.setCellStyle(headerCellStyle);  
  114.   
  115.         HSSFCell cell5 = rowHeader.createCell(startColIndex + 4);  
  116.         cell5.setCellValue("Memory");  
  117.         cell5.setCellStyle(headerCellStyle);  
  118.   
  119.         HSSFCell cell6 = rowHeader.createCell(startColIndex + 5);  
  120.         cell6.setCellValue("Price");  
  121.         cell6.setCellStyle(headerCellStyle);  
  122.   
  123.     }  
  124.   
  125. }  


可以通过 POI单元格顔色设定了解更多的信息.

然后我们是填充数据的一个类:

FillComputerManager.java

Java代码   收藏代码
  1. package org.liukai.tutorial.poi;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.apache.poi.hssf.usermodel.HSSFCell;  
  6. import org.apache.poi.hssf.usermodel.HSSFCellStyle;  
  7. import org.apache.poi.hssf.usermodel.HSSFRow;  
  8. import org.apache.poi.hssf.usermodel.HSSFSheet;  
  9. import org.apache.poi.ss.usermodel.CellStyle;  
  10. import org.liukai.tutorial.domain.Computer;  
  11.   
  12. public class FillComputerManager {  
  13.   
  14.     public static void fillReport(HSSFSheet worksheet, int startRowIndex,  
  15.             int startColIndex, List<Computer> datasource) {  
  16.   
  17.         // Row offset  
  18.         startRowIndex += 2;  
  19.   
  20.         // Create cell style for the body  
  21.         HSSFCellStyle bodyCellStyle = worksheet.getWorkbook().createCellStyle();  
  22.         bodyCellStyle.setAlignment(CellStyle.ALIGN_CENTER);  
  23.         bodyCellStyle.setWrapText(false); //是否自动换行.  
  24.   
  25.         // Create body  
  26.         for (int i=startRowIndex; i+startRowIndex-2< datasource.size()+2; i++) {  
  27.             // Create a new row  
  28.             HSSFRow row = worksheet.createRow((short) i+1);  
  29.   
  30.             // Retrieve the id value  
  31.             HSSFCell cell1 = row.createCell(startColIndex+0);  
  32.             cell1.setCellValue(datasource.get(i-2).getId());  
  33.             cell1.setCellStyle(bodyCellStyle);  
  34.   
  35.             // Retrieve the brand value  
  36.             HSSFCell cell2 = row.createCell(startColIndex+1);  
  37.             cell2.setCellValue(datasource.get(i-2).getBrand());  
  38.             cell2.setCellStyle(bodyCellStyle);  
  39.   
  40.             // Retrieve the model value  
  41.             HSSFCell cell3 = row.createCell(startColIndex+2);  
  42.             cell3.setCellValue(datasource.get(i-2).getCpu());  
  43.             cell3.setCellStyle(bodyCellStyle);  
  44.   
  45.             // Retrieve the maximum power value  
  46.             HSSFCell cell4 = row.createCell(startColIndex+3);  
  47.             cell4.setCellValue(datasource.get(i-2).getGpu());  
  48.             cell4.setCellStyle(bodyCellStyle);  
  49.   
  50.             // Retrieve the price value  
  51.             HSSFCell cell5 = row.createCell(startColIndex+4);  
  52.             cell5.setCellValue(datasource.get(i-2).getMemory());  
  53.             cell5.setCellStyle(bodyCellStyle);  
  54.           
  55.             // Retrieve the efficiency value  
  56.             HSSFCell cell6 = row.createCell(startColIndex+5);  
  57.             cell6.setCellValue(datasource.get(i-2).getPrice());  
  58.             cell6.setCellStyle(bodyCellStyle);  
  59.         }  
  60.     }  
  61. }  


报表写入类

Writer.java
Java代码   收藏代码
  1. package org.liukai.tutorial.poi;  
  2.   
  3. import javax.servlet.ServletOutputStream;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. import org.apache.log4j.Logger;  
  7. import org.apache.poi.hssf.usermodel.HSSFSheet;  
  8.   
  9. public class Writer {  
  10.       
  11.     private static Logger logger = Logger.getLogger("service");  
  12.   
  13.     public static void write(HttpServletResponse response, HSSFSheet worksheet) {  
  14.   
  15.         logger.debug("Writing report to the stream");  
  16.         try {  
  17.             // Retrieve the output stream  
  18.             ServletOutputStream outputStream = response.getOutputStream();  
  19.             // Write to the output stream  
  20.             worksheet.getWorkbook().write(outputStream);  
  21.             // 清除缓存  
  22.             outputStream.flush();  
  23.   
  24.         } catch (Exception e) {  
  25.             logger.error("报表输入失败!");  
  26.         }  
  27.     }  
  28.   
  29. }  

这样对导出表报的格式基本设置完成.

接着我们完成一个对数据库进行操作的类.
PoiDao.java

Java代码   收藏代码
  1. package org.liukai.tutorial.dao;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.annotation.Resource;  
  6. import javax.sql.DataSource;  
  7.   
  8. import org.liukai.tutorial.domain.Computer;  
  9. import org.springframework.jdbc.core.BeanPropertyRowMapper;  
  10. import org.springframework.jdbc.core.namedparam.SqlParameterSource;  
  11. import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;  
  12. import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;  
  13. import org.springframework.stereotype.Repository;  
  14.   
  15. @Repository("poiDao")  
  16. public class PoiDao {  
  17.   
  18.     private SimpleJdbcTemplate jdbcTemplate;  
  19.   
  20.     @Resource(name = "dataSource")  
  21.     public void setDataSource(DataSource dataSource) {  
  22.         this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);  
  23.     }  
  24.   
  25.     public List<Computer> getComputer() {  
  26.         String sql = "SELECT * FROM computer";  
  27.         return jdbcTemplate.query(sql, new BeanPropertyRowMapper<Computer>(  
  28.                 Computer.class));  
  29.   
  30.     }  
  31.   
  32.     public int[] insertComputer(List<Computer> list) {  
  33.         String sql = "INSERT INTO computer (BRAND,CPU,GPU,MEMORY,PRICE)VALUES(:brand,:cpu,:gpu,:memory,:price)";  
  34.         SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(list  
  35.                 .toArray());  
  36.         return jdbcTemplate.batchUpdate(sql, batch);  
  37.   
  38.     }  
  39.   
  40. }  

该类我们实现了两个方法:查询所有的Computer对象并装入一个list的类 : getComputer
批量插入的类:insertComputer
前者用于报表的导出,后者用于报表的插入.

业务层中我们还是需要实现两个业务:导出和导入excel文件.

PoiService.java
Java代码   收藏代码
  1. package org.liukai.tutorial.service;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. import javax.annotation.Resource;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. import org.apache.log4j.Logger;  
  12. import org.apache.poi.hssf.usermodel.HSSFSheet;  
  13. import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
  14. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;  
  15. import org.apache.poi.ss.usermodel.Cell;  
  16. import org.apache.poi.ss.usermodel.DateUtil;  
  17. import org.apache.poi.ss.usermodel.Row;  
  18. import org.apache.poi.ss.usermodel.Sheet;  
  19. import org.apache.poi.ss.usermodel.Workbook;  
  20. import org.apache.poi.ss.usermodel.WorkbookFactory;  
  21. import org.liukai.tutorial.dao.PoiDao;  
  22. import org.liukai.tutorial.domain.Computer;  
  23. import org.liukai.tutorial.poi.FillComputerManager;  
  24. import org.liukai.tutorial.poi.Layouter;  
  25. import org.liukai.tutorial.poi.Writer;  
  26. import org.springframework.stereotype.Service;  
  27. import org.springframework.transaction.annotation.Transactional;  
  28.   
  29. @Service("poiService")  
  30. @Transactional  
  31. public class PoiService {  
  32.   
  33.     @Resource(name = "poiDao")  
  34.     private PoiDao dao;  
  35.     private static Logger logger = Logger.getLogger("service");  
  36.   
  37.     public void exportXLS(HttpServletResponse response) {  
  38.   
  39.         // 1.创建一个 workbook  
  40.         HSSFWorkbook workbook = new HSSFWorkbook();  
  41.   
  42.         // 2.创建一个 worksheet  
  43.         HSSFSheet worksheet = workbook.createSheet("Computer");  
  44.   
  45.         // 3.定义起始行和列  
  46.         int startRowIndex = 0;  
  47.         int startColIndex = 0;  
  48.   
  49.         // 4.创建title,data,headers  
  50.         Layouter.buildReport(worksheet, startRowIndex, startColIndex);  
  51.   
  52.         // 5.填充数据  
  53.         FillComputerManager.fillReport(worksheet, startRowIndex, startColIndex,  
  54.                 getDatasource());  
  55.   
  56.         // 6.设置reponse参数  
  57.         String fileName = "ComputersReport.xls";  
  58.         response.setHeader("Content-Disposition""inline; filename="  
  59.                 + fileName);  
  60.         // 确保发送的当前文本格式  
  61.         response.setContentType("application/vnd.ms-excel");  
  62.   
  63.         // 7. 输出流  
  64.         Writer.write(response, worksheet);  
  65.   
  66.     }  
  67.   
  68.     /** 
  69.      * 读取报表 
  70.      */  
  71.     public List<Computer> readReport(InputStream inp) {  
  72.   
  73.         List<Computer> computerList = new ArrayList<Computer>();  
  74.   
  75.         try {  
  76.             String cellStr = null;  
  77.   
  78.             Workbook wb = WorkbookFactory.create(inp);  
  79.   
  80.             Sheet sheet = wb.getSheetAt(0);// 取得第一个sheets  
  81.   
  82.             //从第四行开始读取数据  
  83.             for (int i = 3; i <= sheet.getLastRowNum(); i++) {  
  84.   
  85.                 Computer computer = new Computer();  
  86.                 Computer addComputer = new Computer();  
  87.   
  88.                 Row row = sheet.getRow(i); // 获取行(row)对象  
  89.   
  90.                 if (row == null) {  
  91.                     // row为空的话,不处理  
  92.                     continue;  
  93.                 }  
  94.   
  95.                 for (int j = 0; j < row.getLastCellNum(); j++) {  
  96.   
  97.                     Cell cell = row.getCell(j); // 获得单元格(cell)对象  
  98.   
  99.                     // 转换接收的单元格  
  100.                     cellStr = ConvertCellStr(cell, cellStr);  
  101.   
  102.                     // 将单元格的数据添加至一个对象  
  103.                     addComputer = addingComputer(j, computer, cellStr);  
  104.   
  105.                 }  
  106.                 // 将添加数据后的对象填充至list中  
  107.                 computerList.add(addComputer);  
  108.             }  
  109.   
  110.         } catch (InvalidFormatException e) {  
  111.             e.printStackTrace();  
  112.         } catch (IOException e) {  
  113.             e.printStackTrace();  
  114.         } finally {  
  115.             if (inp != null) {  
  116.                 try {  
  117.                     inp.close();  
  118.                 } catch (IOException e) {  
  119.                     e.printStackTrace();  
  120.                 }  
  121.             } else {  
  122.                 logger.info("没有数据流!");  
  123.             }  
  124.         }  
  125.         return computerList;  
  126.   
  127.     }  
  128.   
  129.     /** 
  130.      * 从数据库获得所有的Computer信息. 
  131.      */  
  132.     private List<Computer> getDatasource() {  
  133.         return dao.getComputer();  
  134.     }  
  135.   
  136.     /** 
  137.      * 读取报表的数据后批量插入 
  138.      */  
  139.     public int[] insertComputer(List<Computer> list) {  
  140.         return dao.insertComputer(list);  
  141.   
  142.     }  
  143.   
  144.     /** 
  145.      * 获得单元格的数据添加至computer 
  146.      *  
  147.      * @param j 
  148.      *            列数 
  149.      * @param computer 
  150.      *            添加对象 
  151.      * @param cellStr 
  152.      *            单元格数据 
  153.      * @return 
  154.      */  
  155.     private Computer addingComputer(int j, Computer computer, String cellStr) {  
  156.         switch (j) {  
  157.         case 0:  
  158.             computer.setId(null);  
  159.             break;  
  160.         case 1:  
  161.             computer.setBrand(cellStr);  
  162.             break;  
  163.         case 2:  
  164.             computer.setCpu(cellStr);  
  165.             break;  
  166.         case 3:  
  167.             computer.setGpu(cellStr);  
  168.             break;  
  169.         case 4:  
  170.             computer.setMemory(cellStr);  
  171.             break;  
  172.         case 5:  
  173.             computer.setPrice(new Double(cellStr).doubleValue());  
  174.             break;  
  175.         }  
  176.   
  177.         return computer;  
  178.     }  
  179.   
  180.     /** 
  181.      * 把单元格内的类型转换至String类型 
  182.      */  
  183.     private String ConvertCellStr(Cell cell, String cellStr) {  
  184.   
  185.         switch (cell.getCellType()) {  
  186.   
  187.         case Cell.CELL_TYPE_STRING:  
  188.             // 读取String  
  189.             cellStr = cell.getStringCellValue().toString();  
  190.             break;  
  191.   
  192.         case Cell.CELL_TYPE_BOOLEAN:  
  193.             // 得到Boolean对象的方法  
  194.             cellStr = String.valueOf(cell.getBooleanCellValue());  
  195.             break;  
  196.   
  197.         case Cell.CELL_TYPE_NUMERIC:  
  198.   
  199.             // 先看是否是日期格式  
  200.             if (DateUtil.isCellDateFormatted(cell)) {  
  201.   
  202.                 // 读取日期格式  
  203.                 cellStr = cell.getDateCellValue().toString();  
  204.   
  205.             } else {  
  206.   
  207.                 // 读取数字  
  208.                 cellStr = String.valueOf(cell.getNumericCellValue());  
  209.             }  
  210.             break;  
  211.   
  212.         case Cell.CELL_TYPE_FORMULA:  
  213.             // 读取公式  
  214.             cellStr = cell.getCellFormula().toString();  
  215.             break;  
  216.         }  
  217.         return cellStr;  
  218.     }  
  219.   
  220. }  


此业务层实现了两个方法:
exportXLS:用于读取数据库并导出报表.
readReport:用于读取报表并插入数据库中.

untils包里的DateUtils.java只有一个类,用于格式化日期.

DateUtils.java
Java代码   收藏代码
  1. package org.liukai.tutorial.utils;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5.   
  6. public class DateUtils {  
  7.   
  8.     /** 
  9.      * 获得yyyy-MM-dd格式的当前日期 
  10.      */  
  11.     public static String getNowTime() {  
  12.         Date date = new Date();  
  13.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");  
  14.         return dateFormat.format(date);  
  15.     }  
  16.   
  17. }  


最后就是我们的controller层了
PoiController.java

Java代码   收藏代码
  1. package org.liukai.tutorial.controller;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.List;  
  5.   
  6. import javax.annotation.Resource;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9. import org.apache.log4j.Logger;  
  10. import org.liukai.tutorial.domain.Computer;  
  11. import org.liukai.tutorial.service.PoiService;  
  12. import org.springframework.stereotype.Controller;  
  13. import org.springframework.web.bind.annotation.RequestMapping;  
  14. import org.springframework.web.bind.annotation.RequestMethod;  
  15. import org.springframework.web.bind.annotation.RequestParam;  
  16. import org.springframework.web.multipart.MultipartFile;  
  17.   
  18. @Controller  
  19. @RequestMapping("/report")  
  20. public class PoiController {  
  21.   
  22.     private static Logger logger = Logger.getLogger("controller");  
  23.   
  24.     @Resource(name = "poiService")  
  25.     private PoiService service;  
  26.   
  27.     /** 
  28.      * 跳转到主页. 
  29.      */  
  30.     @RequestMapping(value = "", method = RequestMethod.GET)  
  31.     public String getIndex() {  
  32.         logger.info("index!");  
  33.         return "report";  
  34.     }  
  35.   
  36.     /** 
  37.      * 导出excel报表 
  38.      */  
  39.     @RequestMapping(value = "/export", method = RequestMethod.GET)  
  40.     public void getXLS(HttpServletResponse response) {  
  41.         service.exportXLS(response);  
  42.     }  
  43.   
  44.     /** 
  45.      * 读取excel报表 
  46.      */  
  47.     @RequestMapping(value = "/read", method = RequestMethod.POST)  
  48.     public String getReadReport(@RequestParam MultipartFile file)  
  49.             throws IOException {  
  50.         List<Computer> list = service.readReport(file.getInputStream());  
  51.         service.insertComputer(list);  
  52.         return "addedReport";  
  53.   
  54.     }  
  55. }  


到此,后台的代码基本完成了.
下面还有3个JSP页面.

index.jsp
Jsp代码   收藏代码
  1. <% response.sendRedirect("/report"); %>  


report.jsp

Jsp代码   收藏代码
  1. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
  2. <%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>  
  3. <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>  
  4. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  5.     pageEncoding="UTF-8"%>  
  6.   
  7.   
  8. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  9. <html xmlns="http://www.w3.org/1999/xhtml">  
  10. <head>  
  11. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  12. <title>Report</title>  
  13. </head>  
  14. <body>  
  15.     <c:url var="exportUrl" value="/report/export" />  
  16.     <c:url var="readUrl" value="/report/read" />  
  17.       
  18.       
  19.     <h3><a href="${exportUrl }">Export Report</a></h3>  
  20.     <br />  
  21.     <form  id="readReportForm" action="${readUrl }" method="post" enctype="multipart/form-data"  >  
  22.             <label for="file">File</label>  
  23.             <input id="file" type="file" name="file" />  
  24.             <p><button type="submit">Read</button></p>    
  25.         </form>  
  26.       
  27. </body>  
  28. </html>  


addedReport.jsp
Jsp代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  3.     pageEncoding="UTF-8"%>  
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  5. <html xmlns="http://www.w3.org/1999/xhtml">  
  6. <head>  
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  8. <title>Insert title here</title>  
  9. </head>  
  10. <body>  
  11. <h1>导入成功!</h1>  
  12.   
  13. <a href="/spring3-poi/report">返回</a>  
  14. </body>  
  15. </html>  


启动项目后输入:
http://localhost:8080/spring3-poi/report



点击 Export Report我们会得到一个excel文件.
打开后



如此我们通过读取数据库得到了一个excel的文件.

点击"浏览",选择需要导入的excel报表.
注:强烈建议选择我们刚导出的excel报表.因为选择其他的报表格式不同,肯定会报错.
本教程只是演示基本的POI操作.如果要用于生产环境中,请根据自己的状况进行改动和重构.


成功后会显示



这个时候查询数据库,就会发现有2个相同的数据.说明我们导入成功.



总结
本教程中,我们成功的通过使用POI来进行了excel操作
大家可以根据本教程自定义excel的格式,输出的字段.

需要注意的是两点:
1.导入jar包一定要包含poi-ooxml.
2.别忘记关闭InputStream
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值