1. 程式人生 > >SSM POI Excel匯出 封裝類拿走直接用

SSM POI Excel匯出 封裝類拿走直接用

新手上路,經過查詢其他部落格的poi匯出,自己寫了一個限制條件特別多的封裝類,同時又特別實用,希望能幫助大家。

  • 如果使用的不是SSM框架,簡單更改程式碼即可,工具類無需改變。

我使用的框架是maven搭建的SSM框架
匯入poi依賴,這裡使用的是老版本穩定的poi依賴。
最新穩定版本是4.0
下載jar包可以去官網下載

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.6</version>
</dependency>    

為什麼要說我寫的這個封裝類是個限制條件特別多的封裝類呢?
首先,Mybaits配置檔案查詢返回值必須是LinkedHashMap型別,無需使用任何實體類。

將在最後講述為什麼使用LinkedHashMap型別

Mybatis配置檔案:

DAO層,service層

方法返回值均為List<map<String,Object>> 型別

在這裡插入圖片描述

控制器程式碼:

控制器程式碼比較簡單,只需要將response和list傳入進工具類即可。

@Controller
public class XController {
    
    @Resource
    private XService xserivce;

    @RequestMapping("/findAll")
    public String findAll(HttpServletRequest request,HttpServletResponse response) {
        List<Map<String,Object>> list = xserivce.findAll();
        HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook(response,list);
        return "index";
    }
}

excel匯出工具類:

public class ExcelUtil {
	/**
	 * 
	 * @author [email protected]
	 * @param response
	 * @param list
	 * @return HSSFWorkbook
	 */
	public static HSSFWorkbook getHSSFWorkbook(HttpServletResponse response, List<Map<String, Object>> list) {
		// 生成檔名稱
		String fileName = System.currentTimeMillis() + RandomUtils.nextInt(100000) + ".xls";
		// 獲取標題內容
		Set<String> set = new LinkedHashSet<String>();
		Set<String> sets = new LinkedHashSet<String>();

		for (int i = 0; i < list.size(); i++) {
			set = list.get(i).keySet();
			for (String value : set) {
				sets.add(value);
			}
		}
		
		for (int i = 0; i < list.size(); i++) {
			for (String s : sets) {
				if (list.get(i).get(s) == null || list.get(i).get(s) == "") {
					list.get(i).put(s, "");
				}
			}
		}
		// 建立標題長度
		String title[] = new String[sets.size()];
		// 標題內容賦值(賦值,未建立標題)

		int titleSize = 0;
		for (String s : sets) {
			title[titleSize++] = s;
		}

		// 第一步,建立一個HSSFWorkbook,對應一個Excel檔案
		HSSFWorkbook wb = new HSSFWorkbook();

		// 第二步,在workbook中新增一個sheet,對應Excel檔案中的sheet
		HSSFSheet sheet = wb.createSheet("sheet");

		// 第三步,在sheet中新增表頭第0行,注意老版本poi對Excel的行數列數有限制
		HSSFRow row = sheet.createRow(0);

		// 第四步,建立單元格,並設定值表頭 設定表頭居中
		HSSFCellStyle style = wb.createCellStyle();
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 建立一個居中格式

		// 宣告列物件
		HSSFCell cell = null;

		// 建立標題
		for (int i = 0; i < title.length; i++) {
			cell = row.createCell(i);
			cell.setCellValue(title[i]);
			cell.setCellStyle(style);
		}
		// 建立內容
		for (int i = 0; i < list.size(); i++) {
			row = sheet.createRow(i + 1);
			int j = 0;
			for (String s : sets) {
				row.createCell(j++).setCellValue(list.get(i).get(s).toString());
			}
		}

		try {
			setResponseHeader(response, fileName);
			OutputStream os = response.getOutputStream();
			wb.write(os);
			os.flush();
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return wb;
	}

	public static void setResponseHeader(HttpServletResponse response, String fileName) {
		try {
			try {
				fileName = new String(fileName.getBytes(), "ISO8859-1");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			response.setContentType("application/octet-stream;charset=ISO8859-1");
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

}

最後要在最後跳轉的JSP頁面新增上

<%
    out.clear();
    out = pageContext.pushBody();
%>

否則會出現如下錯誤:
在這裡插入圖片描述
報錯原因:
在這裡插入圖片描述

產生這樣的異常原因:是web容器生成的servlet程式碼中有out.write(""),
這個和JSP中呼叫的response.getOutputStream()產生衝突.即Servlet規範說明,
不能既呼叫response.getOutputStream(),又呼叫response.getWriter(),
無論先呼叫哪一個,在呼叫第二個時候應會丟擲IllegalStateException,因為在jsp中,
out變數實際上是通過response.getWriter得到的,你的程式中既用了response.getOutputStream,又用了out變數,故出現以上錯誤。
作者:安_shuai
來源:CSDN
原文:https://blog.csdn.net/xyajia/article/details/78730751
版權宣告:本文為博主原創文章,轉載請附上博文連結!
  
這裡引用其他博主文章,不再進行多餘解釋


最後講述一下為什麼要使用sql返回值為什麼使用LinkedHashMap,LinkedHashMap的Key和Value都允許空,LinkedHashMap會按從資料庫查詢時的順序進行儲存,這樣查詢到的資料就不會順序顛倒。HashMap會導致我們excel表內的內容亂套,比如三個欄位id,name,pass。其中一條資料id值為1,name值為“小明”,pass值為123456,那麼excel表內就會出現這樣的情況

name id pass
小明 1 123456

使用LinkedHashMap就不會出現這種情況,我還嘗試過TreeMap,效果同樣不理想。

哪裡有不足希望大家多多提一下意見,我會努力完善的。