pom
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.0.1</version> </dependency>
导入
SheetHandler
/** * 自定义的事件处理器 * 处理每一行数据读取 * 实现接口 */ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler { private PoiEntity entity; /** * 当开始解析某一行的时候触发 * i:行索引 */ @Override public void startRow(int i) { //实例化对象 if(i>0) { entity = new PoiEntity(); } } /** * 当结束解析某一行的时候触发 * i:行索引 */ @Override public void endRow(int i) { //使用对象进行业务操作 System.out.println(entity); } /** * 对行中的每一个表格进行处理 * cellReference: 单元格名称 * value:数据 * xssfComment:批注 */ @Override public void cell(String cellReference, String value, XSSFComment xssfComment) { List matcher = RegUtil.getMatcher("([a-zA-Z]+)", cellReference); String pix = matcher.get(0).toString(); //对对象属性赋值 if(entity != null) { switch (pix) { case "A": entity.setId(value); break; case "B": entity.setBreast(value); break; case "C": entity.setAdipocytes(value); break; case "D": entity.setNegative(value); break; case "E": entity.setStaining(value); break; case "F": entity.setSupportive(value); break; default: break; } } } }
测试
/** * 使用事件模型解析百万数据excel报表 */ public class PoiTest06 { public static void main(String[] args) throws Exception { long a= System.currentTimeMillis(); String path = "C:\\Users\\ThinkPad\\Desktop\\ihrm\\day8\\资源\\百万数据报表\\demo.xlsx"; File file = new File(path); InputStream inputStream = new FileInputStream(file); //1.根据excel报表获取OPCPackage OPCPackage opcPackage = OPCPackage.open(path, PackageAccess.READ); //OPCPackage opcPackage = OPCPackage.open(inputStream); //2.创建XSSFReader XSSFReader reader = new XSSFReader(opcPackage); //3.获取SharedStringTable对象 SharedStringsTable table = reader.getSharedStringsTable(); //4.获取styleTable对象 StylesTable stylesTable = reader.getStylesTable(); //5.创建Sax的xmlReader对象 XMLReader xmlReader = XMLReaderFactory.createXMLReader(); //6.注册事件处理器 XSSFSheetXMLHandler xmlHandler = new XSSFSheetXMLHandler(stylesTable,table,new SheetHandler(),false); xmlReader.setContentHandler(xmlHandler); //7.逐行读取 XSSFReader.SheetIterator sheetIterator = (XSSFReader.SheetIterator) reader.getSheetsData(); while (sheetIterator.hasNext()) { InputStream stream = sheetIterator.next(); //每一个sheet的流数据 InputSource is = new InputSource(stream); xmlReader.parse(is); } System.out.println("一共耗时:"+(System.currentTimeMillis()-a)/1000); } }
导出
/** * 当月人事报表导出 * 参数: * 年月-月(2018-02%) */ @RequestMapping(value = "/export/{month}", method = RequestMethod.GET) public void export(@PathVariable String month) throws Exception { //1.获取报表数据 List<EmployeeReportResult> list = userCompanyPersonalService.findByReport(companyId,month); //2.构造Excel //创建工作簿 //SXSSFWorkbook : 百万数据报表 //Workbook wb = new XSSFWorkbook(); SXSSFWorkbook wb = new SXSSFWorkbook(100); //阈值,内存中的对象数量最大数量 //构造sheet Sheet sheet = wb.createSheet(); //创建行 //标题 String [] titles = "编号,姓名,手机,最高学历,国家地区,护照号,籍贯,生日,属相,入职时间,离职类型,离职原因,离职时间".split(","); //处理标题 Row row = sheet.createRow(0); int titleIndex=0; for (String title : titles) { Cell cell = row.createCell(titleIndex++); cell.setCellValue(title); } int rowIndex = 1; Cell cell=null; for(int i=0;i<10000;i++){ for (EmployeeReportResult employeeReportResult : list) { row = sheet.createRow(rowIndex++); // 编号, cell = row.createCell(0); cell.setCellValue(employeeReportResult.getUserId()); // 姓名, cell = row.createCell(1); cell.setCellValue(employeeReportResult.getUsername()); // 手机, cell = row.createCell(2); cell.setCellValue(employeeReportResult.getMobile()); // 最高学历, cell = row.createCell(3); cell.setCellValue(employeeReportResult.getTheHighestDegreeOfEducation()); // 国家地区, cell = row.createCell(4); cell.setCellValue(employeeReportResult.getNationalArea()); // 护照号, cell = row.createCell(5); cell.setCellValue(employeeReportResult.getPassportNo()); // 籍贯, cell = row.createCell(6); cell.setCellValue(employeeReportResult.getNativePlace()); // 生日, cell = row.createCell(7); cell.setCellValue(employeeReportResult.getBirthday()); // 属相, cell = row.createCell(8); cell.setCellValue(employeeReportResult.getZodiac()); // 入职时间, cell = row.createCell(9); cell.setCellValue(employeeReportResult.getTimeOfEntry()); // 离职类型, cell = row.createCell(10); cell.setCellValue(employeeReportResult.getTypeOfTurnover()); // 离职原因, cell = row.createCell(11); cell.setCellValue(employeeReportResult.getReasonsForLeaving()); // 离职时间 cell = row.createCell(12); cell.setCellValue(employeeReportResult.getResignationTime()); } } //3.完成下载 ByteArrayOutputStream os = new ByteArrayOutputStream(); wb.write(os); new DownloadUtils().download(os,response,month+"人事报表.xlsx"); }
下载类DownloadUtils
import org.apache.poi.ss.usermodel.Workbook; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class DownloadUtils { public void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException { response.setContentType("application/octet-stream"); returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1")); //保存的文件名,必须和页面编码一致,否则乱码 response.addHeader("Content-Disposition","attachment;filename=total.xls"); response.setContentLength(byteArrayOutputStream.size()); response.addHeader("Content-Length", "" + byteArrayOutputStream.size()); ServletOutputStream outputstream = response.getOutputStream(); //取得输出流 byteArrayOutputStream.writeTo(outputstream); //写到输出流 byteArrayOutputStream.close(); //关闭 outputstream.flush(); //刷数据 } }
2.注解导出
第一步:需要定义注解类
ExcelAttribute.java
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Description * @auther 刘中华 * @create 2019-03-15 11:31 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ExcelAttribute { /** 对应的列名称 */ String name() default ""; /** 列序号 */ int sort(); /** 字段类型对应的格式 */ String format() default ""; }
ExcelAttributeHandle 需要特殊处理的类,比如说男女我们在数据库存的是0和1,导出的肯定不能是01,肯定是男女
/** * @Description * @auther 刘中华 * @create 2019-03-15 13:47 */ public class ExcelAttributeHandle { public static final String TIME="time"; public static final String SIGN="sign"; public static String handle(String type, Object val){ String format= null; switch (type){ case "time": SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(val.getClass()); format = simpleDateFormat.format(val); break; case "sign": format=Integer.valueOf(val.toString())==0?"流入":"流出"; break; } return format; } }
第二步:定义要导出的类
import com.mairuide._frame.utils.excel.annotation.ExcelAttribute; import java.io.Serializable; import java.math.BigDecimal; /** * @Description * @auther 刘中华 * @create 2019-03-15 14:48 */ public class ExceptionAnalysisDetail implements Serializable { /** * 交易主体 */ @ExcelAttribute(name = "交易主体",sort = 0) private String account_body; /** * 交易主体卡号 */ @ExcelAttribute(name = "交易主体卡号",sort = 1) private String account_body_card; /** * 交易对手 */ @ExcelAttribute(name = "交易对手",sort = 2) private String account_rival; /** * 交易主体卡号 */ @ExcelAttribute(name = "交易对手卡号",sort = 3) private String account_rival_card; /** * 时间段 */ @ExcelAttribute(name = "交易日期间隔",sort = 4) private String time_slot; /** * 总交易金额 */ @ExcelAttribute(name = "总交易金额",sort = 5) private BigDecimal sum_account_money; @ExcelAttribute(name = "交易次数",sort = 6) private Integer trade_count;
ExcelExportUtil导出类
import com.mairuide._frame.utils.excel.annotation.ExcelAttribute; import com.mairuide._frame.utils.excel.annotation.ExcelAttributeHandle; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Field; import java.net.URLEncoder; import java.util.List; public class ExcelExportUtil<T> { private int rowIndex; private int styleIndex; private String templatePath; private Class clazz; private Field fields[]; private String[] letter = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; public ExcelExportUtil(Class clazz) { this.clazz = clazz; fields = clazz.getDeclaredFields(); } /** * 基于注解导出 */ public void export(HttpServletResponse response, List<T> objs,String fileName) throws Exception { XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet(); Row title_row = sheet.createRow(0); int cellIndex=0; for (int k = 0; k < fields.length; k++) { Cell cell = title_row.createCell(k); ExcelAttribute ea = fields[k].getAnnotation(ExcelAttribute.class); if(ea!=null && k == ea.sort()) { String name = ea.name(); cell.setCellValue(name); cellIndex=k; } } String addStr = "A0:"+letter[cellIndex]+"0"; CellRangeAddress addr = CellRangeAddress.valueOf(addStr); sheet.setAutoFilter(addr); for (int i = 0; i <objs.size() ; i++) { Row row = sheet.createRow(i+1); for (int j = 0; j <fields.length ; j++ ) { Cell cell = row.createCell(j); if(fields[j].isAnnotationPresent(ExcelAttribute.class)){ fields[j].setAccessible(true); ExcelAttribute ea = fields[j].getAnnotation(ExcelAttribute.class); if(ea!=null && j == ea.sort()&&fields[j].get(objs.get(i))!=null) { if (ea.format()!=null&&!ea.format().equals("")){ cell.setCellValue(ExcelAttributeHandle.handle(ea.format(),fields[j].get(objs.get(i)).toString())); }else{ cell.setCellValue(fields[j].get(objs.get(i)).toString()); } } } } } fileName = URLEncoder.encode(fileName, "UTF-8"); response.setContentType("application/octet-stream"); response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("ISO8859-1"))); response.setHeader("filename", fileName); workbook.write(response.getOutputStream()); } public int getRowIndex() { return rowIndex; } public void setRowIndex(int rowIndex) { this.rowIndex = rowIndex; } public int getStyleIndex() { return styleIndex; } public void setStyleIndex(int styleIndex) { this.styleIndex = styleIndex; } public String getTemplatePath() { return templatePath; } public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } public Class getClazz() { return clazz; } public void setClazz(Class clazz) { this.clazz = clazz; } public Field[] getFields() { return fields; } public void setFields(Field[] fields) { this.fields = fields; } }
调用方法:
//第一步 得到数据 List list = getlist.getRows(); //第二步 下载excel Class clazz= ExceptionAnalysisDetail.class; new ExcelExportUtil(clazz).export(response,list,"异常资金分析.xlsx");