SSM整合開發實戰-poi匯入匯出excel-尾聲
前面介紹了ssm框架的整合開發以及後端介面部分的實現(如今對這些介面有了新的變動以及優化),本文將整合前端框架jquery-easyui來實現前後端介面的對接,更加直接的展示poi匯入匯出excel的效果。(視訊教程地址:https://edu.csdn.net/course/detail/8894 歡迎支援!!)
對於easyui,除了頁面的內容展示以及樣式排版外,主要的責任在於請求後端介面拿到資料並填充到相應的頁面位置中。其中的介面就包括:獲取資料列表,搜尋,匯出資料,匯入資料。
為了展示效果,我結合了企業實際專案中的實際業務模組,就用“產品資訊列表”來進行演示。頁面起名為product.jsp,並在web.xml將其作為welcome-list的歡迎頁面中:
<welcome-file-list>
<!-- <welcome-file>login.jsp</welcome-file> -->
<welcome-file>product.jsp</welcome-file>
</welcome-file-list>
具體的頁面程式碼都在下面了,包括:如果獲取資料列表並填充到easyui的datagrid,匯出資料到excel,開啟對話方塊上傳excel檔案匯入資料等等:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <c:set var="ctx" value="${pageContext.request.contextPath}" ></c:set> <link rel="stylesheet" type="text/css" href="${ctx}/jquery-easyui-1.3.3/themes/default/easyui.css"> <link rel="stylesheet" type="text/css" href="${ctx}/jquery-easyui-1.3.3/themes/icon.css"> <script type="text/javascript" src="${ctx}/jquery-easyui-1.3.3/jquery.min.js"></script> <script type="text/javascript" src="${ctx}/jquery-easyui-1.3.3/jquery.easyui.min.js"></script> <script type="text/javascript" src="${ctx}/jquery-easyui-1.3.3/locale/easyui-lang-zh_CN.js"></script> <script type="text/javascript"> function searchProduct(){ $("#dg").datagrid('load',{ "name":$("#s_productName").val() }); } function exportProduct(){ window.location.href="${ctx}/product/excel/export.do"; } function openUploadFileDialog(){ $("#dlg2").dialog('open').dialog('setTitle','excel批量匯入資料'); } function uploadExcel(){ $("#uploadForm").form("submit",{ success:function(result){ var result=eval('('+result+')'); if(result.code!=0){ $.messager.alert("系統提示",result.msg); }else{ $.messager.alert("系統提示","上傳成功"); $("#dlg2").dialog("close"); $("#dg").datagrid("reload"); } } }); } </script> <title>Insert title here</title> </head> <body style="margin: 1px"> <%-- <table id="dg" title="產品資訊查詢" class="easyui-datagrid" fitColumns="true" pagination="true" rownumbers="true" url="${ctx}/poi/list.do" method="get" fit="true" toolbar="#tb"> --%> <table id="dg" title="產品資訊列表" class="easyui-datagrid" fitColumns="true" pagination="true" rownumbers="true" fit="true" toolbar="#tb" data-options="singleSelect:true,collapsible:true,url:'${ctx}/product/list.do',method:'get'" > <thead> <tr> <th field="cb" checkbox="true" align="center"></th> <th data-options="field:'id',width:50">編號</th> <th data-options="field:'name',width:200">產品名稱</th> <th data-options="field:'unit',width:50">單位</th> <th data-options="field:'price',width:80">價格</th> <th data-options="field:'stock',width:80">庫存</th> <th data-options="field:'remark',width:200">備註</th> <th data-options="field:'purchaseDate',width:100">採購日期</th> </tr> </thead> </table> <div id="tb"> <div> 產品名稱: <input type="text" id="s_productName" size="20" onkeydown="if(event.keyCode==13) searchProduct()"/> <a href="javascript:searchProduct()" class="easyui-linkbutton" iconCls="icon-search" plain="true">搜尋</a> <a href="javascript:exportProduct()" class="easyui-linkbutton" iconCls="icon-search" plain="true">匯出excel</a> <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="openUploadFileDialog()">匯入excel</a> </div> </div> <div id="dlg2" class="easyui-dialog" style="width:400px;height:180px;padding:10px 20px" closed="true" buttons="#dlg-buttons2"> <form id="uploadForm" action="${ctx}/product/excel/upload.do" method="post" enctype="multipart/form-data" > <table> <!-- <tr> <td>下載模版:</td> <td><a href="javascript:void(0)" class="easyui-linkbutton" onclick="downloadTemplate()">下載模板檔案</a></td> </tr> --> <tr> <td>上傳檔案:</td> <td><input type="file" name="productFile"></td> </tr> </table> </form> </div> <div id="dlg-buttons2"> <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-ok" onclick="uploadExcel()">上傳excel</a> <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-cancel" onclick="javascript:$('#dlg2').dialog('close')">關閉</a> </div> </body> </html>
在這裡,後端新增了一個ProductController控制器,用於對接上面頁面的請求介面,具體程式碼如下:
package com.debug.steadyjack.controller; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Workbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import com.debug.steadyjack.dto.BaseResponse; import com.debug.steadyjack.enums.StatusCode; import com.debug.steadyjack.enums.WorkBookVersion; import com.debug.steadyjack.mapper.ProductMapper; import com.debug.steadyjack.model.Product; import com.debug.steadyjack.service.PoiService; import com.debug.steadyjack.service.ProductService; import com.debug.steadyjack.utils.ExcelBeanUtil; import com.debug.steadyjack.utils.ExcelUtil; import com.debug.steadyjack.utils.WebUtil; @Controller public class ProductController { private static final Logger log=LoggerFactory.getLogger(ProductController.class); private static final String prefix="product"; @Value("${poi.excel.sheet.name}") private String sheetProductName; @Value("${poi.excel.file.name}") private String excelProductName; @Autowired private ProductMapper productMapper; @Autowired private PoiService poiService; @Autowired private ProductService productService; /** * 獲取產品列表 * @param name * @return */ @RequestMapping(value=prefix+"/list",method=RequestMethod.GET) @ResponseBody public List<Product> list(String name){ List<Product> products=new ArrayList<Product>(); try { products=productMapper.selectAll(name); } catch (Exception e) { log.error("獲取產品列表發生異常: ",e.fillInStackTrace()); } return products; } /** * 匯出excel * @param response * @return */ @RequestMapping(value=prefix+"/excel/export",method=RequestMethod.GET) public @ResponseBody String exportExcel(HttpServletResponse response,String search){ try { List<Product> products=productMapper.selectAll(search); String[] headers=new String[]{"id編號","名稱","單位","單價","庫存量","採購日期","備註資訊"}; List<Map<Integer, Object>> dataList=ExcelBeanUtil.manageProductList(products); log.info("excel下載填充資料: {} ",dataList); Workbook wb=new HSSFWorkbook(); ExcelUtil.fillExcelSheetData(dataList, wb, headers, sheetProductName); WebUtil.downloadExcel(response, wb, excelProductName); return excelProductName; } catch (Exception e) { log.error("下載excel 發生異常:",e.fillInStackTrace()); } return null; } /** * 上傳excel匯入資料 * @param request * @return */ @SuppressWarnings("rawtypes") @RequestMapping(value=prefix+"/excel/upload",method=RequestMethod.POST,consumes=MediaType.MULTIPART_FORM_DATA_VALUE) @ResponseBody public BaseResponse uploadExcel(MultipartHttpServletRequest request){ BaseResponse response=new BaseResponse<>(StatusCode.Success); try { MultipartFile file=request.getFile("productFile"); if (file==null || file.getName()==null) { return new BaseResponse<>(StatusCode.Invalid_Param); } String fileName=file.getOriginalFilename(); String suffix=StringUtils.substring(fileName, fileName.lastIndexOf(".")+1); if (WorkBookVersion.valueOfSuffix(suffix)==null) { return new BaseResponse<>(StatusCode.WorkBook_Version_Invalid); } log.info("檔名:{} 檔案字尾名:{} ",fileName,suffix); Workbook wb=poiService.getWorkbook(file,suffix); List<Product> products=poiService.readExcelData(wb); //批量插入-第一種方法 //productService.insertBatch(products); //批量插入-第二種方法(注意jdbc連結mysql允許批量插入刪除的配置) productMapper.insertBatch(products); } catch (Exception e) { log.error("上傳excel匯入資料 發生異常:",e.fillInStackTrace()); return new BaseResponse<>(StatusCode.System_Error); } return response; } }
優化過後的PoiService程式碼如下:
package com.debug.steadyjack.service;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.debug.steadyjack.enums.WorkBookVersion;
import com.debug.steadyjack.model.Product;
import com.debug.steadyjack.utils.DateUtil;
import com.debug.steadyjack.utils.ExcelUtil;
@Service
public class PoiService {
private static final Logger log=LoggerFactory.getLogger(PoiService.class);
/**
* 讀取excel資料
* @param wb
* @return
* @throws Exception
*/
public List<Product> readExcelData(Workbook wb) throws Exception{
Product product=null;
List<Product> products=new ArrayList<Product>();
Row row=null;
int numSheet=wb.getNumberOfSheets();
if (numSheet>0) {
for(int i=0;i<numSheet;i++){
Sheet sheet=wb.getSheetAt(i);
int numRow=sheet.getLastRowNum();
if (numRow>0) {
for(int j=1;j<=numRow;j++){
//TODO:跳過excel sheet表格頭部
row=sheet.getRow(j);
product=new Product();
String name=ExcelUtil.manageCell(row.getCell(1), null);
String unit=ExcelUtil.manageCell(row.getCell(2), null);
Double price=Double.valueOf(ExcelUtil.manageCell(row.getCell(3), null));
String stock=ExcelUtil.manageCell(row.getCell(4), null);
String remark=ExcelUtil.manageCell(row.getCell(6), null);
product.setName(name);
product.setUnit(unit);
product.setPrice(price);
product.setStock(Double.valueOf(stock));
String value=ExcelUtil.manageCell(row.getCell(5), "yyyy-MM-dd");
product.setPurchaseDate(DateUtil.strToDate(value, "yyyy-MM-dd"));
product.setRemark(remark);
products.add(product);
}
}
}
}
log.info("獲取資料列表: {} ",products);
return products;
}
/**
* 根據版本來區分獲取workbook例項
* @param version
* @return
*/
public Workbook getWorkbook(String version,InputStream inputStream) throws Exception{
Workbook wk=null;
if (Objects.equals(WorkBookVersion.WorkBook2003.getCode(), version)) {
wk=new HSSFWorkbook(inputStream);
}else if (Objects.equals(WorkBookVersion.WorkBook2007.getCode(), version)) {
wk=new XSSFWorkbook(inputStream);
}
return wk;
}
/**
* 根據file區分獲取workbook例項
* @param version
* @return
*/
public Workbook getWorkbook(MultipartFile file,String suffix) throws Exception{
Workbook wk=null;
if (Objects.equals(WorkBookVersion.WorkBook2003Xls.getCode(), suffix)) {
wk=new HSSFWorkbook(file.getInputStream());
}else if (Objects.equals(WorkBookVersion.WorkBook2007Xlsx.getCode(), suffix)) {
wk=new XSSFWorkbook(file.getInputStream());
}
return wk;
}
}
以及需要用到根據上傳的檔名來決定獲取的WorkBook的例項的WorkBookVersion列舉類:
package com.debug.steadyjack.enums;
import java.util.Objects;
public enum WorkBookVersion {
WorkBook2003("2003","2003版本workBook"),
WorkBook2007("2007","2007版本workBook"),
WorkBook2003Xls("xls","xls字尾名結尾-2003版本workBook"),
WorkBook2007Xlsx("xlsx","xlsx字尾名結尾-2007版本workBook");
private String code;
private String name;
private WorkBookVersion(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*public static WorkBookVersion valueOfVersion(String code){
if (Objects.equals(WorkBook2003.getCode(), code)) {
return WorkBook2003;
}else if (Objects.equals(WorkBook2007.getCode(), code)) {
return WorkBook2007;
}else{
return null;
}
}*/
public static WorkBookVersion valueOfVersion(String version) {
if (Objects.equals(WorkBook2003.getCode(), version)) {
return WorkBook2003;
}else if (Objects.equals(WorkBook2007.getCode(), version)) {
return WorkBook2007;
}else{
return null;
}
}
public static WorkBookVersion valueOfSuffix(String suffix) {
if (Objects.equals(WorkBook2003Xls.getCode(), suffix)) {
return WorkBook2003Xls;
}else if (Objects.equals(WorkBook2007Xlsx.getCode(), suffix)) {
return WorkBook2007Xlsx;
}else{
return null;
}
}
}
到此,就沒有了。然後點選專案右鍵run到tomcat7伺服器,可以看到請求了產品的資料列表,搜尋,匯出資料到Excel以及匯入資料到資料並展示在列表中,詳細截圖如下:
好了,關於springmvc+spring+mybatis整合框架之poi匯入匯出excel這一系列就介紹到這裡來,相關的原始碼已經貼在這幾篇部落格了,有相關問題可以加qq諮詢:1974544863。
另外,為了能介紹得更加清楚,我將特意將此錄製為兩三節小視訊來介紹這個小專案,包括ssm框架的通用搭建法,整合poi框架實現匯入匯出excel以及如何整合easyui框架等等,如果需要,可以加上面qq付費領取(畢竟是自己辛勤付出,總要有點回報!),大概35-50塊低價出售:包括專案原始碼、整體框架搭建的全過程以及實戰視訊、以及售後指導服務!當然啦,如果有需要定製開發的或者有外包的也可以加我上面qq諮詢。