POI多sheet百万数据导出

首先我们约定存储格式:ArrayList<LinkedHashMap<String , Object>>,用LinkedHashMap<String , Object>来存储每条记录信息。具体参考方式见最下面代码

首先我们将上述格式转换成List<String[]>格式的数据,这样只要你符合上述的格式就可以导出任意的数据。具体代码如下

private static List<Object[]> mapDataset(HttpServletRequest request,
			ArrayList<LinkedHashMap<String , Object>> allList, int len) {
		trace.info("alllist------------------------------" + allList.size());
		List<Object[]> dataset = new ArrayList<Object[]>();
		if (allList == null) {
			String str[] = new String[len];
			dataset.add(str);
		} else {
			for (LinkedHashMap<String, Object> map : allList) {// 拿到第i个数据
                //对第i个数组进行迭?
				Iterator<Map.Entry<String, Object>> iter = map.entrySet().iterator();
				int i = 0;
				Object[] str = new Object[map.size()];// 保存数据的字符串数组
				while (iter.hasNext()) {
					Object value = iter.next().getValue();
					if (value == null) {
						str[i] = "";
					} else {
						str[i] = value;
					}
					i++;
				}
				dataset.add(str);
			}
		}
		trace.info("数据大小"+dataset.size());
		return dataset;
	}

然后我们将上述得到的List<String[]>类型数据dataset,利用POI写入excel当中,具体方法如下

	public static void exportExcel(HttpServletRequest request,String rootPath, List<String> title, List<String[]> headers,
			List<Object> dataList, OutputStream out) {
		SXSSFWorkbook  workbook = new SXSSFWorkbook ();
	     int  sheetlen=dataList.size();
	     trace.info("一共生成"+sheetlen+"个表");
	    for (int i = 0; i<sheetlen; i++) {
				// excel中生成一个表
	    	     String titles=title.get(i);
			     Sheet sheet =workbook.createSheet(titles);
			    //给表格加上边框,并且内容居中
			    CellStyle cellStyle= workbook.createCellStyle();
		        cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
		        cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
		        cellStyle.setBottomBorderColor(Font.BOLDWEIGHT_NORMAL);
		        cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
		        cellStyle.setLeftBorderColor(Font.BOLDWEIGHT_NORMAL);
		        cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
		        cellStyle.setRightBorderColor(Font.BOLDWEIGHT_NORMAL);
		        cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
		        cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
		        DataFormat format = workbook.createDataFormat();
		        cellStyle.setDataFormat(format.getFormat("@"));
		        Font titleFont = workbook.createFont();
				titleFont.setFontHeightInPoints((short)10);
				//titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
				cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
				cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
				cellStyle.setFont(titleFont);
				String header[]=headers.get(i);
		        int len =header.length-1;
		        trace.info("表头的长度"+len);
		     // 设置第一行跨的行数,列数
				sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, len));
				Row row0 = sheet.createRow(0);
				Cell ce = row0.createCell(0);
		        ce.setCellValue(titles);
				ce.setCellStyle(cellStyle); // 样式,居�?
				//生成表头信息
				Row row = sheet.createRow(1);
				int width1 = 0;
					for (int k = 0; k <=len; k++){
						Cell cell1 = row.createCell(k);
						width1 = header[k].getBytes().length;
						sheet.setColumnWidth(k,(width1*256*2));
						XSSFRichTextString text = new XSSFRichTextString(header[k]);
						cell1.setCellValue(text);
						cell1.setCellStyle(cellStyle);
						cell1.setCellType(Cell.CELL_TYPE_STRING);
					}
					/**
					 * 生成表格信息
					 */
						ArrayList<LinkedHashMap<String , Object>> listdata=(ArrayList<LinkedHashMap<String, Object>>) dataList.get(i);
						List<Object[]> dataset = mapDataset(request, listdata, header.length);
						Iterator<Object[]> it = dataset.iterator();
						int index = 1;
						while (it.hasNext()) {
							index++;
							row = sheet.createRow(index);
							Object[] t = (Object[]) it.next();
							for (int s = 0; s < t.length; s++) {
								Cell cell = row.createCell(s);
								// sheet.autoSizeColumn((short)i,true);
								// 判断值的类型后进行强制类型转�?
								if (t[s] instanceof Integer) {
									cell.setCellStyle(cellStyle);
									cell.setCellValue((Integer) t[s]);
								} else if (t[s] instanceof Double) {
									cell.setCellStyle(cellStyle);
									cell.setCellValue(Double.parseDouble(t[s] + ""));
								} else if (t[s] instanceof Float) {
									cell.setCellStyle(cellStyle);
									cell.setCellValue(Float.parseFloat(t[s] + ""));
								} else {
									String data = "";
									if (t[s] != null && !"null".equals(t[s])
											&& !"".equals(t[s])) {
										data = t[s] + "";
									}
									if (isValidInt(data)) {
										cell.setCellStyle(cellStyle);
										cell.setCellValue(Integer.parseInt(data));
									} else if (isValidDouble(data)) {
										cell.setCellStyle(cellStyle);
										cell.setCellValue(Double.parseDouble(data + ""));
									} else if (isValidFloat(data)) {
										cell.setCellStyle(cellStyle);
										cell.setCellValue(Float.parseFloat(data + ""));
									} else {
										String textValue = data == null ? "" : (data + "");
										XSSFRichTextString richString = new XSSFRichTextString(textValue);
										cell.setCellValue(richString);
									}
									cell.setCellStyle(cellStyle);
								}
		
							}
						}  		
	      }		
	    try {
			workbook.write(out);
		} catch (IOException e) {
			trace.error("exportExcel IOException " + e.getMessage());
		}		
	    } 	

最后我利用输出流,将文件导出,代码如下

public static synchronized String mapOutToExcel(HttpServletRequest request,
			HttpServletResponse response,String filenames, List<String> title,List<String[]> headers,
			List<Object> allList) {
		OutputStream out = null;// 创建�?��输出流对�?
		try {
			/* 截取掉表名中多余的部�?*/
			filenames = filenames.replaceAll(":", "-");
			filenames = filenames.replaceAll("(", "(");
			filenames = filenames.replaceAll(")", ")");
			String subTitle = filenames;
			String filename = new String((subTitle).getBytes("GB2312"),
					"iso-8859-1");
			// String filename=URLEncoder.encode((title+".xls"), "UTF-8");//IE
			trace.info("@filename:=" + filename);
			out = response.getOutputStream();//
			response.setHeader("Content-disposition", "attachment; filename="
					+ filename + ".xlsx");// filename是下载的xls的名,建议最好用英文
			response.setContentType("application/octet-stream;charset=UTF-8");// 设置类型
			response.setHeader("Pragma", "No-cache");// 设置�?
			response.setHeader("Cache-Control", "no-cache");// 设置�?
			response.setDateHeader("Expires", 0);// 设置日期�?
			String rootPath = request.getSession().getServletContext()
					.getRealPath("/");
			exportExcel(request,rootPath, title, headers, allList, out);
			out.flush();
		} catch (IOException e) {
			trace.error("OutToExcel OutputStream " + e.getMessage());
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				trace.error("OutToExcel OutputStream close " + e.getMessage());
			}
		}
		return null;
	}

这里我们利用for循环实现导出测试

    @RequestMapping(value="/excelPOI.html")
	public void  excelPOI(HttpServletRequest request,HttpServletResponse response){
    	BatchExportExcelUtil export=new BatchExportExcelUtil();
    	String filenames="POI导出的工具类";
    	List<String> title=new ArrayList<String>();
    	List<String[]> header=new ArrayList<String[]>();
    	List<LinkedHashMap<String,Object>> list1=new ArrayList<LinkedHashMap<String,Object>>();
    	List<Object> listall=new ArrayList<Object>();
    	String title1="你好啊";
    	String []head={"姓名","年龄","性别"};
    	title.add(title1);
    	header.add(head);
    	for(int i=0;i<=1000000;i++){
    	LinkedHashMap<String,Object> hashmap=new LinkedHashMap<String,Object>();	
    	hashmap.put("name", "张三");	
    	hashmap.put("age", "25");
    	hashmap.put("sex", "男");
    	list1.add(hashmap);
    	}
    	listall.add(list1);
    	export.mapOutToExcel(request, response, filenames, title, header, listall);

  }

以上是基于SSM框架实现的。

猜你喜欢

转载自blog.csdn.net/weixin_42324471/article/details/82111477