Java分页导出Excel文件

上一篇博客已经讲解了Java怎样导出Excel,但是遇到数据量大时导出时就会有性能问题于是就写了分页导出Excel

1、开发微信小程序接入广告获取收益

技术: Springboot + mongodb + maven +Layui + thymeleaf

导入jar包

	<!-- Excel文件导入 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.9</version>
    </dependency>

前端页面

<div style="padding-bottom: 10px;">
     <button id="js-export" type="button" class="layui-btn btn btn-primary">导出Excel</button>
</div>

//Js
//导出所有数据到Excel ps:参数是你要查询导出数据的条件,全部导出不用加条件
$('#js-export').click(function(){
	window.location.href="/admin/signUserInfo/export?name=" + $("#name").val() + "&sex=" + $("#sex").val() + "&phone=" + $("#phone").val();
});

util工具类

package com.huan.qycq.util;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExcelUtil {

	/**
	 *
	 * @Description: 根据接口 生成 相应的 excel
	 * @author cheng.hao
	 * @param title  excelsheet名称
	 * @param headers  thead
	 * @param jarray   json 返回的jarray
	 * @param infields  传入的 要显示的字段
	 */
	@SuppressWarnings("deprecation")
	public static HSSFSheet createExcelSheet(String title, String[] headers, JSONArray jarray, String[] infields, HSSFWorkbook workbook) throws Exception {
		// 生成一个sheet 并设置名称
		HSSFSheet sheet = workbook.createSheet(title);
		// 设置表格默认列宽度为15个字节
		sheet.setDefaultColumnWidth((short) 20);
		//sheet.setDefaultRowHeightInPoints((float)1.4) ;
		// 生成一个样式
		HSSFCellStyle style = workbook.createCellStyle();
		// 设置这些样式
		style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 生成一个字体
		HSSFFont font = workbook.createFont();
		font.setColor(HSSFColor.VIOLET.index);
		font.setFontHeightInPoints((short) 12);
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 把字体应用到当前的样式
		style.setFont(font);
		// 生成并设置另一个样式
		HSSFCellStyle style2 = workbook.createCellStyle();
		style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
		style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		// 生成另一个字体
		HSSFFont font2 = workbook.createFont();
		font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		// 把字体应用到当前的样式
		style2.setFont(font2);
	/*// 声明一个画图的顶级管理器
	HSSFPatriarch patriarch = sheet.createDrawingPatriarch();*/
		// 产生表格标题行
		HSSFRow row = sheet.createRow(0);
		for (short i = 0; i < headers.length; i++) {
			HSSFCell cell = row.createCell(i);
			cell.setCellStyle(style);
			HSSFRichTextString text = new HSSFRichTextString(headers[i]);
			cell.setCellValue(text);
		}
		// 遍历集合数据,产生数据行
		// Iterator<T> it = dataset.iterator();
		int sames  = 0 ;
		JSONArray j_array_combile = new JSONArray() ;
		for(int i = 0 ;i<jarray.size();i++){
			j_array_combile.add(jarray.getJSONObject(i)) ;
			// 是否是最后一条记录的开关
			boolean last = (i == jarray.size() - 1);
			// 取出相邻的两条记录进行比较
			JSONObject csl1 = null;
			JSONObject csl2 = null;
			if (!last) {
				csl1 = jarray.getJSONObject(i);
				csl2 = jarray.getJSONObject(i + 1);
			} else {
				// 防止最后一条记录无法加入集合
				csl1 = jarray.getJSONObject(i);
				if (jarray.size() != 1)
					csl2 = jarray.getJSONObject(i - 1);
				else
					csl2 = jarray.getJSONObject(i);
			}
			// 默认 是 表头的  第一个字段 进行合并
			if(!csl1.get(infields[0]).toString().equals(csl2.get(infields[0]).toString())){
				JSONObject t_jobj = new JSONObject() ;
				t_jobj.put("sames", sames) ;
				j_array_combile.add(t_jobj) ;
				sames = 0  ;
			}else{
				sames++ ; //
			}
		}

		int index = 0;
		for (int i = 0; i < j_array_combile.size(); i++) {
			JSONObject jobj = j_array_combile.getJSONObject(i);
			if(jobj.get("sames")==null){
				index++;
				row = sheet.createRow(index);
				// 根据传入的 字段数组 取值
				int cellIndex  = 0 ;
				for (String field : infields) {
					HSSFCell cell = row.createCell(cellIndex);
					cell.setCellStyle(style2);
					Object value = jobj.get(field);
					// 判断值的类型后进行强制类型转换
					String textValue = "";
					if(!WebUtils.isEmpty(value)){
						textValue = value.toString();
					}
					if (textValue != null) {
						Pattern p = Pattern.compile("^//d+(//.//d+)?$");
						Matcher matcher = p.matcher(textValue);
						if (matcher.matches()) {
							// 是数字当作double处理
							cell.setCellValue(Double.parseDouble(textValue));
						} else {
							HSSFRichTextString richString = new HSSFRichTextString(textValue);
							HSSFFont font3 = workbook.createFont();
							font3.setColor(HSSFColor.BLUE.index);
							richString.applyFont(font3);
							cell.setCellValue(richString);
						}
					}
					cellIndex++ ;
				}

			}else{
				int same = jobj.getIntValue("sames") ;
				// 进行合并
				if(same!=0)
					sheet.addMergedRegion(new CellRangeAddress((index-same), index, 0, 0));//  横向 合并    第几行 到第几行  第几列 到第几列

			}
		}
		return sheet;
	}
}

Controller

/**
	 * 导出报表
	 * @return
	 */
	@RequestMapping(value = "/export")
	@ResponseBody
	public void export(HttpServletResponse response,
	                   @RequestParam(value = "name", required = false) String name,
	                   @RequestParam(value = "sex", required = false) String sex,
	                   @RequestParam(value = "phone", required = false) String phone) throws Exception {
		File file = new File("exportexcel.xls");
		try {
			// 声明一个工作薄
			HSSFWorkbook workbook2 = new HSSFWorkbook();
			//获取头部标题
			String[] headers = {"用户code","用户名","电话","地址","性别","签到次数"};
			//查询要导出的数据,第一页查1000条
			Page<SignUserInfo> page = signUserInfoService.queryFindSignUserInfos(1, 1000, name, sex, phone);
			//获取显示字段
			String[] infields = {"userCode","name","phone","address","sex","count"};
			//循环分页查询,每页1000条
			int pageNo = 1;
			while(null != page.getData() && page.getData().size() > 0){
				JSONArray jsonArray = new JSONArray();
				for (SignUserInfo entity: page.getData()) {
					JSONObject jsonObj = new JSONObject();
					jsonObj.put("userCode", entity.getUserCode());
					jsonObj.put("name", entity.getName());
					jsonObj.put("phone", entity.getPhone());
					jsonObj.put("address", entity.getAddress());
					jsonObj.put("sex", entity.getSex());
					jsonObj.put("count", entity.getCount());
					jsonArray.add(jsonObj);
				}
				//调用util的方法,写入excel
				ExcelUtil.createExcelSheet("签到信息" + pageNo, headers, jsonArray, infields, workbook2);
				pageNo++;
				//这里循环查要导出的数据,每查一次就是一页
				page = signUserInfoService.queryFindSignUserInfos(pageNo, 1000, name, sex, phone);
			}
			// 告诉浏览器用什么软件可以打开此文件
			response.setHeader("content-Type", "application/vnd.ms-excel");
			// 下载文件的默认名称
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("签到信息.xls", "utf-8"));
			ServletOutputStream out = response.getOutputStream();
			workbook2.write(out);
			out.close();
		} catch (FileNotFoundException e) {
			logger.error(""+e);
		} catch (Exception e) {
			logger.error(""+e);
		}
	}

效果图:Alt

Java中,实现分页导出Excel通常涉及到两个主要步骤:数据分页和将数据写入Excel文件。Apache POI是一个常用库,用于处理Microsoft Office格式的文档,包括Excel。以下是一个简单的示例,展示了如何使用Apache POI进行分页导出Excel: 1. **数据分页**: - 首先,你需要有一个数据源,如列表或数据库查询结果。例如,如果你的数据在`List<YourDataModel>`中,可以计算每页的大小(比如10条记录)并使用`Collections`或数据库API来获取相应页的数据。 ```java List<YourDataModel> dataList = // 获取数据源 int pageSize = 10; int currentPage = 1; // 假设用户选择当前页 int startIndex = (currentPage - 1) * pageSize; List<YourDataModel> pageData = dataList.subList(startIndex, startIndex + pageSize); ``` 2. **创建Excel工作簿和工作表**: - 使用`HSSFWorkbook`创建一个新的Excel工作簿,`HSSFSheet`创建工作表。 ```java HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("Sheet1"); ``` 3. **写入数据到Excel**: - 使用`Row`对象表示行,`Cell`对象表示单元格,将分页数据写入Excel。 ```java Row headerRow = sheet.createRow(0); // 创建表头行 // 填充表头 for (YourDataModel.Field field : YourDataModel.Fields.values()) { Cell cell = headerRow.createCell(field.getIndex()); cell.setCellValue(field.getName()); } for (YourDataModel data : pageData) { Row row = sheet.createRow(sheet.getLastRowNum() + 1); // 创建新行 for (YourDataModel.Field field : data.getFieldValues()) { Cell cell = row.createCell(field.getIndex()); cell.setCellValue(field.getValue()); } } ``` 4. **保存Excel文件**: - 最后,将工作簿写入磁盘文件。 ```java try (FileOutputStream fileOut = new FileOutputStream("output.xlsx")) { workbook.write(fileOut); } catch (IOException e) { e.printStackTrace(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值