工作時遇到了一個excel 導出的問題 , 原本是想直接用前端的table直接做excel 導出,但是又發現有點不滿足需求
是 同是將三個小表格放入到一個excel表格中去,於是就上網找資料
這篇貼子就寫的比較清楚詳細 於是快樂的抄襲就開始了,但是發現一些不足之處,於是就稍微改動了一下,覺得還是滿足使用的
#貼上代碼
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.*;
import java.util.*;
public class ExcelUtil {
static HSSFCellStyle style;
/**
* 導出Excel
*
* @param sheetName sheet名稱
* @param title 標題
* @param values 內容
* @param wb HSSFWorkbook對象
* @return
*/
public static HSSFWorkbook getHSSFWorkbook(String sheetName, String[] title, List<Map<String, Object>> values, HSSFWorkbook wb) {
// 第一步,創建一個HSSFWorkbook
if (wb == null) {
wb = new HSSFWorkbook();
style = getStyle(wb);
/*創建一個sheet*/
HSSFSheet sheet = wb.createSheet(sheetName);
/*設置標題*/
setTitle(sheet, title);
/*將map裏的數據設置到sheet 中去*/
setData(sheet, values);
} else {
style = getStyle(wb);
HSSFSheet sheet = wb.getSheet(sheetName);
setTitle(sheet, title);
setData(sheet, values);
}
return wb;
}
private static void setTitle(HSSFSheet sheet, String[] title) {
int lastRowNum = sheet.getLastRowNum();
/*獲取 最後一行的行號*/
HSSFRow row = sheet.createRow(lastRowNum + 1);
for (int i = 0; i < title.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(title[i]);
cell.setCellStyle(style);
}
}
/**
* 構建樣式
*
* @param wb
* @return
*/
private static HSSFCellStyle getStyle(HSSFWorkbook wb) {
HSSFCellStyle style = wb.createCellStyle();
// 創建一個居中格式
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
return style;
}
/**
* 填充數據的方法
*
* @param sheet
* @param mapList
*/
private static void setData(HSSFSheet sheet, List<Map<String, Object>> mapList) {
int i = sheet.getLastRowNum();
for (Map<String, Object> value : mapList) {
HSSFRow row = sheet.createRow(i + 1);
int j = 0;
for (Map.Entry<String, Object> entry : value.entrySet()) {
//將內容按順序賦給對應的列對象
row.createCell(j).setCellValue((String) entry.getValue());
j++;
}
i++;
}
}
public static void main(String[] args) {
String sheetName = "學生信息表";//Sheet名稱
/*說明: 如果是用map的話 必須使用linkHashMap 這樣的數據纔是有序的,否則就是無序的*/
Map<String, Object> map = new LinkedHashMap<>();
List<Map<String, Object>> mapList = new ArrayList<>();
map.put("name", "小明");
map.put("sex", "男");
map.put("age", "10");
map.put("class", "廣東小學");
map.put("school", "三年二班");
mapList.add(map);
String[] title = {"名稱", "性別", "年齡", "學校", "班級"};
//excel文件名
String fileName = "D://學生信息表" + System.currentTimeMillis() + ".xls";
//第一次加載數據
HSSFWorkbook workbook = getHSSFWorkbook(sheetName, title, mapList, null);
//同一個sheet 中添加其他信息
Map<String, Object> map1 = new LinkedHashMap<>();
List<Map<String, Object>> mapList1 = new ArrayList<>();
map1.put("hight", "165cm");
map1.put("weight", "80kg");
map1.put("like", "打籃球");
mapList1.add(map1);
String[] titles = {"身高", "體重", "愛好"};
workbook = getHSSFWorkbook(sheetName, titles, mapList1, workbook);
OutputStream os = null;
try {
os = new FileOutputStream(new File(fileName));
workbook.write(os);
os.flush();
os.close();
System.out.println("successful");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#測試結果是
剛剛好滿足我的要求
補充: 由於寫日誌的時候快要下班了,但是啓動項目的時候發現一個異常, 異常就是springBoot 不兼容poi 3.6的版本,所以重新換了4.0.0的版本才得以生效
#貼出前端的代碼
/**
* 導出excel表格
*
* @param request
* @param response
* @return
* @author Lengff
* @time 2018-11-1 18:43:06
*/
@RequestMapping("export")
@ResponseBody
public void export(HttpServletRequest request, HttpServletResponse response) {
String sheetName = "全站概況統計";
String fileName = "全站概況統計" + System.currentTimeMillis() + ".xls";
String[] title = {"統計", "新增激活設備", "新增註冊數", "新增註冊轉化率", "新增註冊數", "啓動量", "活躍啓動量", "平均啓動次數", "登錄人數", "登錄轉化率"};
String[] titlB = {"統計", "累計激活設備", "累計註冊數", "註冊轉化率"};
List<Map<String, Object>> todayCount = siteCountService.getTodayCount(1);
HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook(sheetName, title, todayCount, null);
List<Map<String, Object>> countYesterday = siteCountService.getTodayCount(2);
wb = ExcelUtil.getHSSFWorkbook(sheetName, title, countYesterday, wb);
List<Map<String, Object>> countAll = siteCountService.countAll();
wb = ExcelUtil.getHSSFWorkbook(sheetName, titlB, countAll, wb);
try {
this.setResponseHeader(response, fileName);
OutputStream os = response.getOutputStream();
wb.write(os);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//發送響應流方法
private void setResponseHeader(HttpServletResponse response, String fileName) {
try {
try {
fileName = new String(fileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
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();
}
}
成功的導出excel文件
#最後的結果
總結:excel 導出其實是用的比較多的功能 , 實現的方式也有很多種, 之前也做過很多種 , 但是覺得都挺麻煩的, 唯獨這次的方式比較方便, 因爲是把bean 轉成了map , 所以就不需要考慮 對應關係, 但是要注意的是必須是用linkHashMap 要不然就會亂序,一樣會讓人頭疼不已的!