java 导出百万数据到excel
@RequestMapping("export") public void write(HttpServletRequest request,HttpServletResponse response,String agent,String starttime, String endtime,int callduration,String dst,String answer) { try { Map<String,Object> param = new HashMap<>(); User user = (User) request.getSession().getAttribute(Constant.LOGIN_USER); param.put("agent", agent); param.put("starttime", starttime == "" ? DateUtil.getFirstDayByMonth() : starttime); param.put("endtime", endtime == "" ? DateUtil.getLastDayByMonth() : endtime); param.put("callduration", callduration); param.put("dst",dst); param.put("answer",answer); if(DateUtil.isThisMonth(param.get("starttime").toString()) && DateUtil.isThisMonth(param.get("endtime").toString())){ param.put("cdr", "cdr"+user.getPbxid()); }else{ param.put("cdr", "cdr"+user.getPbxid()+"_"+DateUtil.getYearAndMonth(param.get("starttime").toString())); } // 创建CSV写对象 查询数据 List<Map<String, Object>> list = this.cdrService.listCdrs(param); // 写入临时文件 File tempFile = File.createTempFile("vehicle", ".csv"); CsvWriter csvWriter = new CsvWriter(tempFile.getCanonicalPath(), ',', Charset.forName("UTF-8")); // 写表头 String headers[] = new String[]{"id", "主叫", "被叫", "开始时间", "应答时间", "结束时间", "总时长(秒)", "通话时长(秒)", "通话状态","挂断方"}; csvWriter.writeRecord(headers); for(int i = 0;i<list.size();i++){ csvWriter.write(list.get(i).get("clid").toString()==null? "" :list.get(i).get("clid").toString()); csvWriter.write(list.get(i).get("src").toString()==null? "" :list.get(i).get("src").toString()); csvWriter.write(list.get(i).get("dst").toString()==null? "" :list.get(i).get("dst").toString()); csvWriter.write(list.get(i).get("start").toString()==null? "" :list.get(i).get("start").toString()); csvWriter.write(list.get(i).get("answer").toString()==null? "" :list.get(i).get("answer").toString()); csvWriter.write(list.get(i).get("end").toString()==null? "" :list.get(i).get("end").toString()); Integer billsec = Integer.parseInt(list.get(i).get("billsec").toString()); Integer duration = Integer.parseInt(list.get(i).get("duration").toString()); csvWriter.write(String.valueOf(billsec+duration)); csvWriter.write(list.get(i).get("billsec").toString()==null? "" :list.get(i).get("billsec").toString()); String disposition = list.get(i).get("disposition").toString(); if (disposition.equals("ANSWERED")) { csvWriter.write("已接通"); } else if (disposition.equals("NO ANSWER")) { csvWriter.write("未接通"); } else if (disposition.equals("BUSY")) { csvWriter.write("忙碌"); } else if (disposition.equals("FILED")) { csvWriter.write("失败"); } else { csvWriter.write(""); } String hanger = list.get(i).get("hanger").toString(); if (Integer.parseInt(hanger)==-1) { csvWriter.write("客户挂断"); } else { csvWriter.write("坐席挂断"); } csvWriter.endRecord(); } csvWriter.close(); /** * 写入csv结束,写出流 */ java.io.OutputStream out = response.getOutputStream(); byte[] b = new byte[10240]; java.io.File fileLoad = new java.io.File(tempFile.getCanonicalPath()); response.setContentType("application/csv"); response.setHeader("content-disposition", "attachment; filename="+ DateUtil.getDate()+".csv");
out.write("\ufeff".getBytes()); long fileLength = fileLoad.length(); String length1 = String.valueOf(fileLength); response.setHeader("Content_Length", length1); java.io.FileInputStream in = new java.io.FileInputStream(fileLoad); int n; while ((n = in.read(b)) != -1) { out.write(b, 0, n); // 每次写入out1024字节 } in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } }
注意:如果是数字类型太长超过16位写入到excel会丢失
解决办法 将 csvWriter.write 改成 csvWriter.writeRecord()
把长数字转换成字符串,并在输在字符串前面增加“\t”。
例如:
String un = list.get(i).get("uniqueid").toString().replaceFirst("#", ""); String[] u = new String[]{"\t"+un}; csvWriter.writeRecord(u,true);