基于POI导出Excel数据
在项目中会有许多报表业务,需要导出数据。在这里我们采用基于POI的方式解析。POI有俩种解析方式HSSF(xls格式)和XSSF(xlsx)。
以BOS物流的运单管理界面为例:
前端代码
导出运单信息,生成报表:
1.添加导出按钮
2.添加导出事件
后台代码实现
POI生成Excel步骤写Excel过程一样,新建Excel文档----新建Sheet---新建Row---新建Cell单元格---写单元格数据。
Maven导入jar包信息请参加一键上传里面的配置
Action层代码实现
@Controller @Scope("prototype") @ParentPackage("json-default") @Namespace("/") public class ExportXlsAction extends BaseAction<WayBill>{ @Autowired private WayBillService wayBillService; @Action("report_exportXls") public String exportXls() throws Exception{ //查询出,满足当前条件的结果数据 List<WayBill> waybills = wayBillService.findwayBills(model); // 生成Excel文件(xls格式) HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); HSSFSheet sheet = hssfWorkbook.createSheet("运单数据");//创建一个sheet对象 // 表头(表格的第一行) HSSFRow headRow = sheet.createRow(0);//创建第一行对象 headRow.createCell(0).setCellValue("运单号");//创建了第一个格子它的属性是运单号 headRow.createCell(1).setCellValue("寄件人");//创建了第二个格子... headRow.createCell(2).setCellValue("寄件人电话"); headRow.createCell(3).setCellValue("寄件人地址"); headRow.createCell(4).setCellValue("收件人"); headRow.createCell(5).setCellValue("收件人电话"); headRow.createCell(6).setCellValue("收件人地址"); // 表格数据(遍历拿到的数据,一个对象信息对应一行记录) for (WayBill wayBill : waybills) {//拿到最后一行的行号 HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1); dataRow.createCell(0).setCellValue(wayBill.getWayBillNum()); dataRow.createCell(1).setCellValue(wayBill.getSendName()); dataRow.createCell(2).setCellValue(wayBill.getSendMobile()); dataRow.createCell(3).setCellValue(wayBill.getSendAddress()); dataRow.createCell(4).setCellValue(wayBill.getRecName()); dataRow.createCell(5).setCellValue(wayBill.getRecMobile()); dataRow.createCell(6).setCellValue(wayBill.getRecAddress()); } // 下载导出 // 设置头信息(设置文件类型 xls) ServletActionContext.getResponse().setContentType( "application/vnd.ms-excel"); String filename = "运单数据.xls"; String agent = ServletActionContext.getRequest() .getHeader("user-agent");//得到浏览器类型(火狐,360,IE) filename = FileUtils .encodeDownloadFilename(filename, agent); ServletActionContext.getResponse().setHeader("Content-Disposition", "attachment;filename=" + filename); //filename:设置生产Excel的文件名 FileUtils:是针对浏览器类型的中文编码类 ServletOutputStream outputStream = ServletActionContext.getResponse() .getOutputStream();//得到一个响应流对象 hssfWorkbook.write(outputStream); // 关闭 hssfWorkbook.close(); return NONE; } }
package cn.itcast.bos.utils; import java.io.IOException; import java.net.URLEncoder; import sun.misc.BASE64Encoder; public class FileUtils { /** * 下载文件时,针对不同浏览器,进行附件名的编码 * * @param filename * 下载文件名 * @param agent * 客户端浏览器 * @return 编码后的下载附件名 * @throws IOException */ public static String encodeDownloadFilename(String filename, String agent) throws IOException { if (agent.contains("Firefox")) { // 火狐浏览器 filename = "=?UTF-8?B?" + new BASE64Encoder().encode(filename.getBytes("utf-8")) + "?="; filename = filename.replaceAll("\r\n", ""); } else { // IE及其他浏览器 filename = URLEncoder.encode(filename, "utf-8"); filename = filename.replace("+"," "); } return filename; } }
public List<WayBill> findwayBills(WayBill wayBill) { if (StringUtils.isBlank(wayBill.getWayBillNum()) && StringUtils.isBlank(wayBill.getSendAddress()) && StringUtils.isBlank(wayBill.getRecAddress()) && StringUtils.isBlank(wayBill.getSendProNum()) && (wayBill.getSignStatus() == null || wayBill.getSignStatus() == 0)) { // 无条件查询 、查询数据库 return wayBillRepository.findAll(); } else { // 查询条件 // must 条件必须成立 and // must not 条件必须不成立 not // should 条件可以成立 or BoolQueryBuilder query = new BoolQueryBuilder(); // 布尔查询 ,多条件组合查询 // 向组合查询对象添加条件 if (StringUtils.isNoneBlank(wayBill.getWayBillNum())) { // 运单号查询 QueryBuilder tempQuery = new TermQueryBuilder("wayBillNum", wayBill.getWayBillNum()); query.must(tempQuery); } if (StringUtils.isNoneBlank(wayBill.getSendAddress())) { //发货地的模糊查询 //情况一:输入“北”是查询词条的一部分,使用模糊匹配词条查询 QueryBuilder wildcardQuery = new WildcardQueryBuilder( "sendAddress", "*" + wayBill.getSendAddress() + "*"); //情况二:输入“北京市海淀区”是多个词条组合,进行分词后每个词条匹配查询 QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(wayBill.getSendAddress()) .field("sendAdress").defaultOperator(Operator.AND); //俩种情况取or关系 BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); boolQueryBuilder.should(queryStringQueryBuilder); boolQueryBuilder.should(wildcardQuery); query.must(boolQueryBuilder); } if (StringUtils.isNoneBlank(wayBill.getRecAddress())) { // 收货地 模糊查询 QueryBuilder wildcardQuery = new WildcardQueryBuilder( "recAddress", "*" + wayBill.getRecAddress() + "*"); query.must(wildcardQuery); } if (StringUtils.isNoneBlank(wayBill.getSendProNum())) { // 速运类型 等值查询 QueryBuilder termQuery = new TermQueryBuilder("sendProNum", wayBill.getSendProNum()); query.must(termQuery); } if (StringUtils.isNoneBlank(wayBill.getSendProNum())) { // 速运类型 等值查询 QueryBuilder termQuery = new TermQueryBuilder("sendProNum", wayBill.getSendProNum()); query.must(termQuery); } if (wayBill.getSignStatus() != null && wayBill.getSignStatus() != 0) { // 签收状态查询 QueryBuilder termQuery = new TermQueryBuilder("signStatus", wayBill.getSignStatus()); query.must(termQuery); } SearchQuery searchQuery = new NativeSearchQuery(query); // Integer.MAX_VALUE:方便获取所有查询到的数据 Pageable pageable = new PageRequest(0, Integer.MAX_VALUE); searchQuery.setPageable(pageable ); // 分页效果 // 有条件查询 、查询索引库 return wayBillIndexRepository.search(searchQuery).getContent(); } }
package cn.itcast.bos.dao.index; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import cn.itcast.bos.domain.take_delivery.WayBill; //多条件查询走的是缓存 public interface WayBillIndexRepository extends ElasticsearchRepository<WayBill, Integer> { }
最终实现效果:
因为对POI的API了解不多,打印出来的Excel数据排版是手动调整的。