SSM學習筆記(三)——excel匯入匯出
阿新 • • 發佈:2019-01-05
非專門的軟體企業用的比較多的便是excel的匯入和匯出的功能,本次對近日實現的匯入和匯出功能做下記錄。
首先是工具類,這裡參考了CSDN “如果海豚會飛” 的文章,但由於其文章內容有些殘缺,且與QB個人開發的現狀不符合,所以做了一定的修改。
參考的文章:http://blog.csdn.net/hsf15768615284/article/details/73136029
注意的導包:poi的幾個包,xmlbeans這個包(因為這個包沒匯入QB除錯了6個多小時才找到錯誤,感覺虧了一個億)
工具類:
建立一個ExcelBean實現資料的封裝
ExcelBean.java
package cn.gsp.common.utils.excel; import org.apache.poi.xssf.usermodel.XSSFCellStyle; /** * @Description: 建立一個ExcelBean實現資料的封裝 * @author QB * @date 2017年10月17日 上午9:19:00 */ public class ExcelBean implements java.io.Serializable { /** * @Fields serialVersionUID : TODO(用一句話描述這個變量表示什麼) */ private static final long serialVersionUID = 1L; private String headTextName;// 列頭(標題)名 private String propertyName;// 對應欄位名 private Integer cols;// 合併單元格數 private XSSFCellStyle cellStyle; public ExcelBean() { } public ExcelBean(String headTextName, String propertyName) { this.headTextName = headTextName; this.propertyName = propertyName; } public ExcelBean(String headTextName, String propertyName, Integer cols) { super(); this.headTextName = headTextName; this.propertyName = propertyName; this.cols = cols; } public String getHeadTextName() { return headTextName; } public void setHeadTextName(String headTextName) { this.headTextName = headTextName; } public String getPropertyName() { return propertyName; } public void setPropertyName(String propertyName) { this.propertyName = propertyName; } public Integer getCols() { return cols; } public void setCols(Integer cols) { this.cols = cols; } public XSSFCellStyle getCellStyle() { return cellStyle; } public void setCellStyle(XSSFCellStyle cellStyle) { this.cellStyle = cellStyle; } }
excel的匯入工具類(這裡QB只採用了原博主的匯入工具類,同時也進行了一些符合自己現狀的修改)
ExcelUtil.java
匯出的工具類package cn.gsp.common.utils.excel; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; 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.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFFont; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.sun.org.apache.xerces.internal.impl.xpath.regex.ParseException; public class ExcelUtil { private final static String excel2003L = ".xls"; // 2003- 版本的excel private final static String excel2007U = ".xlsx"; // 2007+ 版本的excel /** * Excel匯入 */ public static List<List<Object>> getBankListByExcel(InputStream in, String fileName) throws Exception { List<List<Object>> list = null; // 建立Excel工作薄 Workbook work = getWorkbook(in,fileName); if ( null==work) { throw new Exception("建立Excel工作薄為空!"); } Sheet sheet = null; Row row = null; Cell cell = null; list = new ArrayList<List<Object>>(); // 遍歷Excel中所有的sheet for (int i = 0; i < work.getNumberOfSheets(); i++) { sheet = work.getSheetAt(i); if (sheet == null) { continue; } // 遍歷當前sheet中的所有行 // 包涵頭部,所以要小於等於最後一列數,這裡也可以在初始值加上頭部行數,以便跳過頭部 for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) { // 讀取一行 row = sheet.getRow(j); // 去掉空行和表頭 if (row == null || row.getFirstCellNum() == j) { continue; } // 遍歷所有的列 List<Object> li = new ArrayList<Object>(); for (int y = 0; y <3; y++) { //由於個人原因被明確規定了匯入資料只有三列, cell = row.getCell(y); //且 考慮到匯入的excel單元格內可以不寫東西得情況 if(cell==null) //所以直接用 明確的數值來確定遍歷的次數 {li.add(null);} //這裡添加了單元格中空白的判斷,如果空白預設賦值為null,避免後面mybatis裡面出現錯誤 else li.add(getCellValue(cell)); } list.add(li); } } return list; } /** * 描述:根據檔案字尾,自適應上傳檔案的版本 */ public static Workbook getWorkbook(InputStream inStr, String fileName) throws Exception { Workbook wb = null; String fileType = fileName.substring(fileName.lastIndexOf(".")); if (excel2003L.equals(fileType)) { wb = new HSSFWorkbook(inStr); // 2003- } else if (excel2007U.equals(fileType)) { wb = new XSSFWorkbook(inStr); // 2007+ } else { throw new Exception("解析的檔案格式有誤!"); } return wb; } /** * 描述:對錶格中數值進行格式化 */ public static Object getCellValue(Cell cell) { Object value = null; DecimalFormat df = new DecimalFormat("0"); // 格式化字元型別的數字 SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd"); // 日期格式化 DecimalFormat df2 = new DecimalFormat("0.00"); // 格式化數字 switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: value = cell.getRichStringCellValue().getString(); break; case Cell.CELL_TYPE_NUMERIC: if ("General".equals(cell.getCellStyle().getDataFormatString())) { value = df.format(cell.getNumericCellValue()); } else if ("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) { value = sdf.format(cell.getDateCellValue()); } else { value = df2.format(cell.getNumericCellValue()); } break; case Cell.CELL_TYPE_BOOLEAN: value = cell.getBooleanCellValue(); break; case Cell.CELL_TYPE_BLANK: value = ""; break; default: break; } return value; }
ViewExcel.java
package cn.gsp.common.utils; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.springframework.web.servlet.view.document.AbstractExcelView; public class ViewExcel extends AbstractExcelView { private String[] titles; // 傳入指定的標題頭 public ViewExcel(String[] titles) { this.titles = titles; } @Override protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取資料 List<Map<String, String>> list = (List<Map<String, String>>) model.get("excelList"); // 在workbook新增一個sheet HSSFSheet sheet = workbook.createSheet(); sheet.setDefaultColumnWidth(15); HSSFCell cell = null; // 遍歷標題 for (int i = 0; i < titles.length; i++) { // 獲取位置 cell = getCell(sheet, 0, i); setText(cell, titles[i]); } // 資料寫出 for (int i = 0; i < list.size(); i++) { // 獲取每一個map Map<String, String> map = list.get(i); // 一個map一行資料 HSSFRow row = sheet.createRow(i + 1); for (int j = 0; j < titles.length; j++) { // 遍歷標題,把key與標題匹配 String title = titles[j]; // 判斷該內容存在mapzhong if (map.containsKey(title)) { row.createCell(j).setCellValue(map.get(title)); } } } // 設定下載時客戶端Excel的名稱 String filename = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".xls"; response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=" + filename); OutputStream ouputStream = response.getOutputStream(); workbook.write(ouputStream); ouputStream.flush(); ouputStream.close(); } }
這裡的匯入指的是將excel檔案上傳,匯入到資料庫中,然後進行相應的規則應用(匯入匯出只是附帶功能,但這裡只記錄匯入匯出的部分)
匯出指的是將資料從資料庫中匯出,生成excel檔案(目前正在想是否直接匯出查詢結果會更好?但感覺好麻煩。。。)
匯入jsp部分
<form method="post" enctype="multipart/form-data"
action="${pageContext.request.contextPath }/seorder/import.action">
<table>
<tr>
<td>上傳檔案:</td>
<td><input id="upfile" type="file" name="upfile"
class="btn btn-blue"></td>
</tr>
<tr>
<td><input class="btn btn-blue" type="submit" value="提交"
onclick="return checkData()"></td>
</tr>
</table>
</form>
controller部分
/**
* excel表的匯入
*/
@RequestMapping("/import")
public String impotr(HttpServletRequest request, Model model) throws Exception {
// 獲取上傳的檔案
MultipartHttpServletRequest multipart = (MultipartHttpServletRequest) request;
MultipartFile file = multipart.getFile("upfile");
if (file.isEmpty()) {
JOptionPane.showMessageDialog(null, "上傳檔案為空!", "錯誤", JOptionPane.ERROR_MESSAGE);
return "redirect:/seorder/list.action";
} // 對上傳檔案是否為空做了一個判斷,如果excel不存在彈出錯誤提示框頁面重定向,存在匯入excel
InputStream in = file.getInputStream();
// 資料匯入
seorderService.importExcelInfo(in, file);
return "redirect:/seorder/pipei.action";
}
service部分
/**
* 匯入excel
*/
public void importExcelInfo(InputStream in, MultipartFile file) throws Exception {
List<List<Object>> listob = ExcelUtil.getBankListByExcel(in, file.getOriginalFilename());
List<SeorderK> seorderList = new ArrayList<SeorderK>();
// 遍歷listob資料,把資料放到List中
for (int i = 0; i < listob.size(); i++) {
List<Object> ob = listob.get(i);
SeorderK seorderK = new SeorderK();
// 通過遍歷實現把每一列封裝成一個model中,再把所有的model用List集合裝載
seorderK.setFBillNo(String.valueOf(ob.get(0)));
seorderK.setFMapNumber(String.valueOf(ob.get(1)));
seorderK.setFEntrySelfS0164(String.valueOf(ob.get(2)));
// seorderK.setFNumber(String.valueOf(ob.get(3))); 考慮到實際的情況讓使用者只用匯入三個欄位中的兩個就可以了
// seorderK.setFShortNumber(String.valueOf(ob.get(4)));
// seorderK.setFName(String.valueOf(ob.get(5)));
seorderList.add(seorderK);
}
// 批量插入
seorderkDao.insertInfoBatch(seorderList);
}
dao部分
/**
* 匯入資料
* @param seorderkList
*/
public void insertInfoBatch(List<SeorderK> seorderkList);
dao的實現類xml
<!-- 匯入資料 -->
<insert id="insertInfoBatch" parameterType="java.util.List">
insert into gsp_seorderk_t (FBillNo, FMapNumber,FEntrySelfS0164)
values
<foreach collection="list" item="item" index="index"
separator="," >
(#{item.FBillNo}, #{item.FMapNumber}, #{item.FEntrySelfS0164})
</foreach>
</insert>
匯入部分到此為止,接下來是匯出的部分
匯出jsp部分
<form
action="${pageContext.request.contextPath }/seorder/export.action">
<button id="btnExport" type="submit" class="btn btn-blue">匯出</button>
</form>
controller部分
/**
* 匯出excel2
*
* @param map
* @return
* @throws Exception
*/
@RequestMapping("/export")
public ModelAndView export(ModelMap map) throws Exception {
List<Map<String, String>> list = seorderService.exportExcelInfo();
String[] titles = { "訂單編號", "客戶程式碼", "新編碼", "GSP長程式碼", "GSP短程式碼", "GSP名稱" };
ViewExcel excel = new ViewExcel(titles);
map.put("excelList", list);
return new ModelAndView(excel, map);
}
service部分
/**
* 匯出excel2
*
* @throws Exception
*/
public List<Map<String, String>> exportExcelInfo() throws Exception {
List<SeorderK> list = seorderkDao.pipei(null);
List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
for (SeorderK sk : list) {
Map<String, String> map = new HashMap<String, String>();
map.put("訂單編號", sk.getFBillNo());
map.put("客戶程式碼", sk.getFMapNumber());
map.put("新編碼", sk.getFEntrySelfS0164());
map.put("GSP長程式碼", sk.getFNumber());
map.put("GSP短程式碼", sk.getFShortNumber());
map.put("GSP名稱", sk.getFName());
mapList.add(map);
}
return mapList;
}
dao部分
/**
* 匯出excel
* @param seorderkDate
* @return
*/
public List<SeorderK> selectApartInfo(String seorderkDate);
dao對應的實現類xml
依據個人情況來寫