POI操作Excel 2003,2007后续版本是非常方便的,但是有时候我们需要创建的行数会很多或者列数很多,
对于程序猿来说,不可能用手动创建这种笨拙的方法 → _ →!!。
本示例读取模板后自动创建行,自动创建列(列数多少跟对象有多少属性相关)
本示例读取模板为例。
正题:
@ResponseBody
@RequestMapping("/export/excel")
public void excelExport(HttpServletResponse res, HttpServletRequest req){
String filePath = req.getSession().getServletContext().getRealPath("/template/20170426.xlsx");
String fileName = "2017-01-01";
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(filePath));//读取excel模板
XSSFSheet sheet = workbook.getSheetAt(0);// 获取模板第一个sheet
XSSFCellStyle style = workbook.getSheetAt(0).getRow(1).getCell(22).getCellStyle();//获取单元格样式
List<TPaimaiExcelExportDto> exports = new ArrayList<TPaimaiExcelExportDto>();//模拟数据
for (int i = 0; i < 50; i++) {
createRow(exports, workbook, sheet, style);//创建数据行
}
res.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("GB2312"), "ISO_8859_1"));
workbook.write(os);
os.flush();
os.close();
}
/**
* <p>
* 创建数据行
* </p>
*
* @param exports 数据
* @param workbook excel
* @param sheet sheet
* @param style 单元格样式
*/
private void createRow(List<TPaimaiExcelExportDto> exports, XSSFWorkbook workbook, XSSFSheet sheet, XSSFCellStyle style) {
try {
if (workbook != null) {
XSSFRow row;
XSSFCell cell = null;
int rowNum = sheet.getLastRowNum();// 获取最后一行行号
Map<String, String> map = new HashMap<String, String>();
for (TPaimaiExcelExportDto excelExportDto : exports) {//遍历需要打印的数据
row = sheet.createRow(rowNum + 1);//创建行
row.setHeightInPoints(23);//设置行高
//列数太多,读取对象属性,属性顺序按照excel表格定义
Field[] fields = excelExportDto.getClass().getDeclaredFields();// 获取对象属性(私有属性) 10个属性 就会创建10列
String cellText = "-";
if (fields != null) {
for (int i = 0; i < fields.length; i++) {
Field fd = fields[i];
fd.setAccessible(true);
Object obj = fd.get(excelExportDto);// 获取属性值
cellText = formatCellContext(obj, fd.getName());//格式化单元格数据
createCell(i, cellText, row, cell, style);//生成单元格
}
}
rowNum++;//换行
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* <p>
* 生成单元格
* </p>
*
* @param cellNum 列
* @param text 单元格内容
* @param row 行
* @param cell 单元格
* @param style 单元格样式
*/
private void createCell(int cellNum, String text, XSSFRow row, XSSFCell cell, XSSFCellStyle style) {
cell = row.createCell(cellNum);//创建单元格
cell.setCellValue(new XSSFRichTextString(text));//设置单元格内容
cell.setCellStyle(style);//设置单元格样式
}
/**
* 格式化单元格内容
*
* @param value 属性
* @param propertyName 属性名称(此参数主要为了判断对某个属性做特殊处理)
*if ("withLicenseYn".equals(propertyName)) { //示例
* if (valCode == 10000000) {
* cellContext = "否";
* } else if (valCode == 10000001) {
* cellContext = "是";
* }
* }
* @return
*/
private String formatCellContext(Object value, String propertyName) {
String cellContext = "-";
//格式化double,保留两位小数
if (value instanceof Double) {
Double dub = (Double) value;
cellContext = String.format("%.2f", object);
}else if (value instanceof Date) {
//格式化日期
Date date = (Date) value;
cellContext = DateUtil.simpleDateFormat(date, "yyyy/MM/dd");
}else if (value instanceof String) {
//字符串直接返回,除非有特殊处理
cellContext = object.toString();
}else if (value instanceof Integer) {
//integer也可直接返回,除非有特出处理
Integer valCode = (Integer) value;
cellContext = valCode.toString();
}else{
//其他数据类型根据需要添加
cellContext = "-";
}
return cellContext;
}
效果: