java导出excel案例

JA V A实现EXCEL的导入和导出(四)JA V A EXCEL API简介Java Excel是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容、创建新的Excel文件、更新已经存在的Excel文件。

使用该API非Windows操作系统也可以通过纯Java应用来处理Excel数据表。

因为是使用Java编写的,所以我们在Web应用中可以通过JSP、Servlet来调用API实现对Excel数据表的访问。

现在发布的稳定版本是V2.0,提供以下功能:* 从Excel 95、97、2000等格式的文件中读取数据;* 读取Excel公式(可以读取Excel 97以后的公式);* 生成Excel数据表(格式为Excel 97);* 支持字体、数字、日期的格式化;* 支持单元格的阴影操作,以及颜色操作;* 修改已经存在的数据表;现在还不支持以下功能,但不久就会提供了:1. 不能够读取图表信息;2. 可以读,但是不能生成公式,任何类型公式最后的计算值都可以读出;回页首应用示例1 从Excel文件读取数据表Java Excel API既可以从本地文件系统的一个文件(.xls),也可以从输入流中读取Excel数据表。

读取Excel数据表的第一步是创建Workbook(术语:工作薄),下面的代码片段举例说明了应该如何操作:(完整代码见ExcelReading.java)import java.io.*;import jxl.*;… … … …try{//构建Workbook对象, 只读Workbook对象//直接从本地文件创建Workbook//从输入流创建WorkbookInputStream is = new FileInputStream(sourcefile);jxl.Workbook rwb = Workbook.getWorkbook(is);}catch (Exception e){e.printStackTrace();}一旦创建了Workbook,我们就可以通过它来访问Excel Sheet(术语:工作表)。

参考下面的代码片段://获取第一张Sheet表Sheet rs = rwb.getSheet(0);我们既可能通过Sheet的名称来访问它,也可以通过下标来访问它。

如果通过下标来访问的话,要注意的一点是下标从0开始,就像数组一样。

一旦得到了Sheet,我们就可以通过它来访问Excel Cell(术语:单元格)。

参考下面的代码片段://获取第一行,第一列的值Cell c00 = rs.getCell(0, 0);String strc00 = c00.getContents();//获取第一行,第二列的值Cell c10 = rs.getCell(1, 0);String strc10 = c10.getContents();//获取第二行,第二列的值Cell c11 = rs.getCell(1, 1);String strc11 = c11.getContents();System.out.println("Cell(0, 0)" + " value : " + strc00 + "; type : " + c00.getType());System.out.println("Cell(1, 0)" + " value : " + strc10 + "; type : " + c10.getType());System.out.println("Cell(1, 1)" + " value : " + strc11 + "; type : " + c11.getType());如果仅仅是取得Cell的值,我们可以方便地通过getContents()方法,它可以将任何类型的Cell值都作为一个字符串返回。

示例代码中Cell(0, 0)是文本型,Cell(1, 0)是数字型,Cell(1,1)是日期型,通过getContents(),三种类型的返回值都是字符型。

如果有需要知道Cell内容的确切类型,API也提供了一系列的方法。

参考下面的代码片段:String strc00 = null;double strc10 = 0.00;Date strc11 = null;Cell c00 = rs.getCell(0, 0);Cell c10 = rs.getCell(1, 0);Cell c11 = rs.getCell(1, 1);if(c00.getType() == BEL){LabelCell labelc00 = (LabelCell)c00;strc00 = labelc00.getString();}if(c10.getType() == CellType.NUMBER){NmberCell numc10 = (NumberCell)c10;strc10 = numc10.getV alue();}if(c11.getType() == CellType.DA TE){DateCell datec11 = (DateCell)c11;strc11 = datec11.getDate();}System.out.println("Cell(0, 0)" + " value : " + strc00 + "; type : " + c00.getType());System.out.println("Cell(1, 0)" + " value : " + strc10 + "; type : " + c10.getType());System.out.println("Cell(1, 1)" + " value : " + strc11 + "; type : " + c11.getType());在得到Cell对象后,通过getType()方法可以获得该单元格的类型,然后与API提供的基本类型相匹配,强制转换成相应的类型,最后调用相应的取值方法getXXX(),就可以得到确定类型的值。

API提供了以下基本类型,与Excel的数据格式相对应,如下图所示:每种类型的具体意义,请参见Java Excel API Document。

当你完成对Excel电子表格数据的处理后,一定要使用close()方法来关闭先前创建的对象,以释放读取数据表的过程中所占用的内存空间,在读取大量数据时显得尤为重要。

参考如下代码片段://操作完成时,关闭对象,释放占用的内存空间rwb.close();Java Excel API提供了许多访问Excel数据表的方法,在这里我只简要地介绍几个常用的方法,其它的方法请参考附录中的Java Excel API Document。

Workbook类提供的方法1. int getNumberOfSheets()获得工作薄(Workbook)中工作表(Sheet)的个数,示例:jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));int sheets = rwb.getNumberOfSheets();2. Sheet[] getSheets()返回工作薄(Workbook)中工作表(Sheet)对象数组,示例:jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));Sheet[] sheets = rwb.getSheets();3. String getV ersion()返回正在使用的API的版本号,好像是没什么太大的作用。

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));String apiV ersion = rwb.getV ersion();Sheet接口提供的方法1) String getName()获取Sheet的名称,示例:jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));jxl.Sheet rs = rwb.getSheet(0);String sheetName = rs.getName();2) int getColumns()获取Sheet表中所包含的总列数,示例:jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));jxl.Sheet rs = rwb.getSheet(0);int rsColumns = rs.getColumns();3) Cell[] getColumn(int column)获取某一列的所有单元格,返回的是单元格对象数组,示例:jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));jxl.Sheet rs = rwb.getSheet(0);Cell[] cell = rs.getColumn(0);4) int getRows()获取Sheet表中所包含的总行数,示例:jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));jxl.Sheet rs = rwb.getSheet(0);int rsRows = rs.getRows();5) Cell[] getRow(int row)获取某一行的所有单元格,返回的是单元格对象数组,示例子:jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));jxl.Sheet rs = rwb.getSheet(0);Cell[] cell = rs.getRow(0);6) Cell getCell(int column, int row)获取指定单元格的对象引用,需要注意的是它的两个参数,第一个是列数,第二个是行数,这与通常的行、列组合有些不同。

合集下载

java导出包含多个sheet的Excel代码示例

java导出包含多个sheet的Excel代码示例

java导出包含多个sheet的Excel代码⽰例本⽂实例为⼤家分享了java导出包含多个sheet的Excel的具体代码,供⼤家参考,具体内容如下要导出多个sheet,关键就是Excel导出的时间设定,在执⾏导出⽂件之前,创建多个⼯作表HSSFSheet sheet = workbook.createSheet(sheettitle);这样每创建⼀个⼯作表,便会⽣成⼀个新的sheet表,在最后导出Excel的时候⼀次性导出。

⽰例:Java类:try {HSSFWorkbook workbook = new HSSFWorkbook();OutputStream out = response.getOutputStream();for(int j=0;j<n;j++){BaseResult<List<T>> teasalList = service.select(teasal);//接下来循环list放到Excel表中if(teasalList.isSuccess()&&teasalList.getResult().size()>0){//⽂件标题SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");String nowdate = formatter1.format(new Date());String title = null;title = "excel表格标题-" + nowdate + ".xls";String sheettitle = "sheet表名";//设置表格标题⾏String oneheaders = "⾸⾏标题" ;String dateheaders = nowdate ;String[] headers = new String[] {"列1","列2","列3","列4"};List<Object[]> dataList = new ArrayList<Object[]>();Object[] objs = null;for(int i =0; i<3 ; i++){ //循环每⼀条数据objs = new Object[headers.length];objs[1] = "张三"; //姓名objs[2] = "3"; //序号//数据添加到excel表格dataList.add(objs);}//使⽤流将数据导出//防⽌中⽂乱码String headStr = "attachment; filename=\"" + new String( title.getBytes("gb2312"), "ISO8859-1" ) + "\"";response.setContentType("octets/stream");response.setContentType("APPLICATION/OCTET-STREAM");response.setHeader("Content-Disposition", headStr);ExportExcelDownFee ex ;ex = new ExportExcelDownFee(sheettitle, oneheaders, dateheaders,headers, dataList);//没有标题ex.export(workbook,out);}}workbook.write(out); //循环⽣成多个sheet之后在导出Excelout.close(); //关闭流} catch (Exception e) {e.printStackTrace();}⼯具类:public class ExportExcelDownFee {//导出表的列名private String[] rowName ;//导出表的⼩标题private String oneheaders;//导出表的⽇期private String dateheaders;//sheet表表名private String sheettitle;private List<Object[]> dataList = new ArrayList<Object[]>();HttpServletResponse response;//构造⽅法2,传⼊要导出的数据public ExportExcelDownFee( String sheettitle, String oneheaders, String dateheaders, String[] rowName,List<Object[]> dataList){ this.dataList = dataList;this.oneheaders = oneheaders;this.dateheaders = dateheaders;this.rowName = rowName;this.sheettitle = sheettitle;}/** 导出数据* */public void export(HSSFWorkbook workbook,OutputStream out) throws Exception{try{HSSFSheet sheet = workbook.createSheet(sheettitle); // 创建⼯作表HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);//获取列头样式对象HSSFCellStyle style = this.getStyle(workbook); //单元格样式对象//第⼀⾏HSSFRow rowfirstName = sheet.createRow(0);HSSFCell oneCellRowName = rowfirstName.createCell(0); //创建列头对应个数的单元格oneCellRowName.setCellType(HSSFCell.CELL_TYPE_STRING); //设置列头单元格的数据类型HSSFRichTextString onetext = new HSSFRichTextString(oneheaders);oneCellRowName.setCellValue(onetext); //设置列头单元格的值//合并单元格CellRangeAddress构造参数依次表⽰起始⾏,截⾄⾏,起始列,截⾄列sheet.addMergedRegion(new CellRangeAddress(0,0,0,3));oneCellRowName.setCellStyle(columnTopStyle); //设置列头单元格样式//第⼆⾏HSSFRow rowDateName = sheet.createRow(1);HSSFCell DateCellRowName = rowDateName.createCell(3);DateCellRowName.setCellValue(dateheaders);DateCellRowName.setCellStyle(columnTopStyle);// 定义所需列数int columnNum = rowName.length;HSSFRow rowRowName = sheet.createRow(2); // 在索引2的位置创建⾏(最顶端的⾏开始的第⼆⾏)// 将列头设置到sheet的单元格中for(int n=0;n<columnNum;n++){HSSFCell cellRowName = rowRowName.createCell(n); //创建列头对应个数的单元格cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING); //设置列头单元格的数据类型HSSFRichTextString text = new HSSFRichTextString(rowName[n]);cellRowName.setCellValue(text); //设置列头单元格的值cellRowName.setCellStyle(style); //设置列头单元格样式}//将查询出的数据设置到sheet对应的单元格中for(int i=0;i<dataList.size();i++){Object[] obj = dataList.get(i);//遍历每个对象HSSFRow row = sheet.createRow(i+3);//创建所需的⾏数(从第⼆⾏开始写数据)for(int j=0; j<obj.length; j++){HSSFCell cell = null; //设置单元格的数据类型if(j == 0){cell = row.createCell(j,HSSFCell.CELL_TYPE_NUMERIC);cell.setCellValue(i+1);}else{cell = row.createCell(j,HSSFCell.CELL_TYPE_STRING);if(!"".equals(obj[j]) && obj[j] != null){cell.setCellValue(obj[j].toString()); //设置单元格的值}}cell.setCellStyle(style); //设置单元格样式}}//让列宽随着导出的列长⾃动适应for (int colNum = 0; colNum < columnNum; colNum++) {int columnWidth = sheet.getColumnWidth(colNum) / 256;for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {HSSFRow currentRow;//当前⾏未被使⽤过if (sheet.getRow(rowNum) == null) {currentRow = sheet.createRow(rowNum);} else {currentRow = sheet.getRow(rowNum);}if (currentRow.getCell(colNum) != null) {HSSFCell currentCell = currentRow.getCell(colNum);if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) { int length = 0;try {length = currentCell.getStringCellValue().getBytes().length;} catch (Exception e) {e.printStackTrace();}if (columnWidth < length) {columnWidth = length;}}}}if(colNum == 0){sheet.setColumnWidth(colNum, (columnWidth-2) * 256);}else{sheet.setColumnWidth(colNum, (columnWidth+4) * 256);}}}catch(Exception e){e.printStackTrace();}}/** 列头单元格样式*/public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) { // 设置字体HSSFFont font = workbook.createFont();//设置字体⼤⼩font.setFontHeightInPoints((short)11);//字体加粗//font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//设置字体名字font.setFontName("宋体");//设置样式;HSSFCellStyle style = workbook.createCellStyle();//在样式⽤应⽤设置的字体;style.setFont(font);//设置⾃动换⾏;style.setWrapText(false);//设置⽔平对齐的样式为居中对齐;style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//设置垂直对齐的样式为居中对齐;style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);return style;}/** 列数据信息单元格样式*/public HSSFCellStyle getStyle(HSSFWorkbook workbook) {// 设置字体HSSFFont font = workbook.createFont();//设置字体名字font.setFontName("宋体");//设置样式;HSSFCellStyle style = workbook.createCellStyle();//设置底边框;style.setBorderBottom(HSSFCellStyle.BORDER_THIN);//设置底边框颜⾊;style.setBottomBorderColor(HSSFColor.BLACK.index);//设置左边框;style.setBorderLeft(HSSFCellStyle.BORDER_THIN);//设置左边框颜⾊;style.setLeftBorderColor(HSSFColor.BLACK.index);//设置右边框;style.setBorderRight(HSSFCellStyle.BORDER_THIN);//设置右边框颜⾊;style.setRightBorderColor(HSSFColor.BLACK.index);//设置顶边框;style.setBorderTop(HSSFCellStyle.BORDER_THIN);//设置顶边框颜⾊;style.setTopBorderColor(HSSFColor.BLACK.index);//在样式⽤应⽤设置的字体;style.setFont(font);//设置⾃动换⾏;style.setWrapText(false);//设置⽔平对齐的样式为居中对齐;style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//设置垂直对齐的样式为居中对齐;style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);return style;}}以上所述是⼩编给⼤家介绍的java导出包含多个sheet的Excel代码⽰例详解整合,希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。

java实现导出Excel(跨行跨列)

java实现导出Excel(跨行跨列)

java实现导出Excel(跨行跨列)在Java中,可以使用Apache POI库来实现导出Excel文件,并且可以实现跨行和跨列的功能。

Apache POI是一个开源的Java库,可以处理Microsoft Office格式的文档,包括Excel。

以下是使用Apache POI库实现导出Excel文件的步骤:1. 首先,需要引入Apache POI依赖。

可以在Maven或Gradle中添加以下依赖项:```xml<!-- Apache POI --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency>2. 创建一个Workbook对象,该对象代表一个Excel文件:```javaWorkbook workbook = new XSSFWorkbook(;```3. 创建一个Sheet对象,该对象代表Excel文件中的一个工作表:```javaSheet sheet = workbook.createSheet("Sheet1");```4. 创建行和单元格,根据需要设置跨行和跨列的属性。

可以使用CellRangeAddress类来实现跨行和跨列的功能:```javaRow row = sheet.createRow(0);Cell cell = row.createCell(0);cell.setCellValue("跨行跨列");//合并单元格,从第1行到第3行,从第1列到第5列CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 2, 0, 4);sheet.addMergedRegion(cellRangeAddress);5. 将数据写入Excel文件中的单元格:```javaRow row = sheet.createRow(0);Cell cell = row.createCell(0);cell.setCellValue("Hello");```6. 将Workbook对象写入到文件中:```javaFileOutputStream fileOutputStream = new FileOutputStream("output.xlsx");workbook.write(fileOutputStream);fileOutputStream.close(;```完整的示例代码如下所示:```javaimport ermodel.*;import org.apache.poi.ss.util.CellRangeAddress;import ermodel.XSSFWorkbook;import java.io.FileOutputStream;import java.io.IOException;public class ExcelExporterpublic static void main(String[] args) throws IOExceptionWorkbook workbook = new XSSFWorkbook(;Sheet sheet = workbook.createSheet("Sheet1");Row row = sheet.createRow(0);Cell cell = row.createCell(0);cell.setCellValue("跨行跨列");//合并单元格,从第1行到第3行,从第1列到第5列CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 2, 0, 4);sheet.addMergedRegion(cellRangeAddress);FileOutputStream fileOutputStream = newFileOutputStream("output.xlsx");workbook.write(fileOutputStream);fileOutputStream.close(;System.out.println("Excel文件导出成功!");}```执行该代码后,会在项目的根目录下生成一个名为`output.xlsx`的Excel文件,其中包含一个跨行和跨列的单元格。

JAVA实现Excel导入导出以及excel样式设置

JAVA实现Excel导入导出以及excel样式设置

JAVA实现Excel导⼊导出以及excel样式设置JAVA实现Excel导⼊/导出以及excel样式设置图2.1 POI的⽬录结构 POI使⽤初步 POI提供给⽤户使⽤的对象在ermodel包中,主要部分包括Excel对象、样式和格式,还有辅助操作等。

最主要的⼏个对象如表3.1所⽰: 表3.1 POI主要对象POI对象名称对应的Excel对象HSSFWorkbook⼯作簿HSSFSheet⼯作表HSSFRow⾏HSSFCell单元格 下⾯我们来看如下的例⼦,使⽤表3.1中的对象在程序的当前⽬录下创建⼀个Excel⽂件test.xls,在第⼀个单元格中写⼊内容,然后读出第⼀个单元格的内容。

完整的程序如下:import ermodel.HSSFWorkbook;import ermodel.HSSFSheet;import ermodel.HSSFRow;import ermodel.HSSFCell;import java.io.FileOutputStream;import java.io.FileInputStream;public class CreateXL{ public static String xlsFile="test.xls"; //产⽣的Excel⽂件的名称 public static void main(String args[]) { try { HSSFWorkbook workbook = new HSSFWorkbook(); //产⽣⼯作簿对象 HSSFSheet sheet = workbook.createSheet(); //产⽣⼯作表对象 //设置第⼀个⼯作表的名称为firstSheet //为了⼯作表能⽀持中⽂,设置字符编码为UTF_16 workbook.setSheetName(0,"firstSheet",HSSFWorkbook.ENCODING_UTF_16); //产⽣⼀⾏ HSSFRow row = sheet.createRow((short)0); //产⽣第⼀个单元格 HSSFCell cell = row.createCell((short) 0); //设置单元格内容为字符串型 cell.setCellType(HSSFCell.CELL_TYPE_STRING); //为了能在单元格中写⼊中⽂,设置字符编码为UTF_16。

java导出excel浏览器直接下载或者或以文件形式导出

java导出excel浏览器直接下载或者或以文件形式导出

java导出excel浏览器直接下载或者或以⽂件形式导出看代码吧~/*** excel表格直接下载*/public static void exportExcelByDownload(HSSFWorkbook wb,HttpServletResponse httpServletResponse,String fileName) throws Exception {//响应类型为application/octet- stream情况下使⽤了这个头信息的话,那就意味着不想直接显⽰内容httpServletResponse.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);//attachment为以附件⽅式下载httpServletResponse.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName + ".xls","utf-8"));/*** 代码⾥⾯使⽤Content-Disposition来确保浏览器弹出下载对话框的时候。

* response.addHeader("Content-Disposition","attachment");⼀定要确保没有做过关于禁⽌浏览器缓存的操作*/httpServletResponse.setHeader("Cache-Control", "No-cache");httpServletResponse.flushBuffer();wb.write(httpServletResponse.getOutputStream());wb.close();}/*** excel以⽂件的形式导出* @throws Exception*/public static void exportExcelByFile(HSSFWorkbook wb,String fileName,String path) throws Exception{ByteArrayOutputStream stream = new ByteArrayOutputStream();wb.write(stream);FileOutputStream outputStream = new FileOutputStream(path + fileName);outputStream.write(stream.toByteArray());stream.close();outputStream.close();}java查询数据导出excel并返回给浏览器下载效果图:1.点击导出表按钮2.接着就会出现下图3.点击上图中的确定按钮再接着就会出现下图4.点击上图中的保存按钮接着就会出现下图,浏览器下载完成后的提⽰5.打开下载好的⽂件如下图好了,废话不多少,上代码jsp前端代码<div style="height:30px;"><a>时间:</a><input id="startDateConsume" type="text" class="easyui-datebox"> <a>-</a><input id="endDateConsume" type="text" class="easyui-datebox"><a>消费类型:</a><select id="consumesType" name=""><option value="0" selected="selected">所有</option><option value="1">报名费</option><option value="2">酒⽔零⾷类</option></select><a>⽀付状态:</a><select id="conPaymentStatus" name=""><option value="0" selected="selected">所有</option><option value="1">未⽀付</option><option value="2">已⽀付</option></select><a id="btnConsumesSearch" class="easyui-linkbutton"data-options="iconCls:'icon-search'" style="margin-left:10px">查询</a><a>(查询出来的数据可统计)</a><a id="consumesOutExcel" class="easyui-linkbutton" style="" data-options="iconCls:'icon-redo'">导出表</a></div>js前端代码$(function() {//导出excel表$('#consumesOutExcel').on('click',function(){exportExcel();});});function exportExcel() {$.messager.confirm('确认', '确认把该搜索结果导出Excel表格?', function(r) {if (r) {var startTime = $('#startDateConsume').val();var endTime = $('#endDateConsume').val();var consumesType = $('#consumesType').val();var conPaymentStatus = $('#conPaymentStatus').val();$.messager.progress({title : '处理中',msg : '请稍后',});$.messager.progress('close');location.href="web/vip/exportExcel.xlsx?startTime=" rel="external nofollow" +startTime+"&endTime="+endTime+"&consumesType="+consumesType+"&conPaymentStatus="+conPaymentStatus; }});}java后端代码@Controller@RequestMapping("/vip")public class VipController {//⽂件下载:导出excel表@RequestMapping(value = "/exportExcel.xlsx",method = RequestMethod.GET)@ResponseBodypublic void exportExcel(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException{//⼀、从后台拿数据if (null == request || null == response){return;}List<VipConsumes> list = null;String startTime = request.getParameter("startTime");String endTime = request.getParameter("endTime");int consumesType = Integer.parseInt(request.getParameter("consumesType"));int conPaymentStatus =Integer.parseInt(request.getParameter("conPaymentStatus"));VipConsumesExample example = new VipConsumesExample();if(consumesType!=0 && conPaymentStatus!=0){example.createCriteria().andTimeBetween(startTime, endTime).andConsumeTypeEqualTo(consumesType).andStatusEqualTo(conPaymentStatus);}else if(consumesType ==0 && conPaymentStatus!=0) {example.createCriteria().andTimeBetween(startTime, endTime).andStatusEqualTo(conPaymentStatus);}else if(consumesType!=0 && conPaymentStatus==0){example.createCriteria().andTimeBetween(startTime, endTime).andConsumeTypeEqualTo(consumesType);}else {example.createCriteria().andTimeBetween(startTime, endTime);}list = this.vipConsumesDao.selectByExample(example);//⼆、数据转成excelrequest.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");response.setContentType("application/x-download");String fileName = "消费记录.xlsx";fileName = URLEncoder.encode(fileName, "UTF-8");response.addHeader("Content-Disposition", "attachment;filename=" + fileName); // 第⼀步:定义⼀个新的⼯作簿XSSFWorkbook wb = new XSSFWorkbook();// 第⼆步:创建⼀个Sheet页XSSFSheet sheet = wb.createSheet("startTimeendTime");sheet.setDefaultRowHeight((short) (2 * 256));//设置⾏⾼sheet.setColumnWidth(0, 4000);//设置列宽sheet.setColumnWidth(1,5500);sheet.setColumnWidth(2,5500);sheet.setColumnWidth(3,5500);sheet.setColumnWidth(11,3000);sheet.setColumnWidth(12,3000);sheet.setColumnWidth(13,3000);XSSFFont font = wb.createFont();font.setFontName("宋体");font.setFontHeightInPoints((short) 16);XSSFRow row = sheet.createRow(0);XSSFCell cell = row.createCell(0);cell.setCellValue("流⽔号 ");cell = row.createCell(1);cell.setCellValue("微信名 ");cell = row.createCell(2);cell.setCellValue("微信订单号");cell = row.createCell(3);cell.setCellValue("消费时间");cell = row.createCell(4);cell.setCellValue("消费类型");cell = row.createCell(5);cell.setCellValue("剩余积分 ");cell = row.createCell(6);cell.setCellValue("新增积分 ");cell = row.createCell(7);cell.setCellValue("扣除积分 ");cell = row.createCell(8);cell.setCellValue("消费⾦额");cell = row.createCell(9);cell.setCellValue("⽀付⽅式");cell = row.createCell(10);cell.setCellValue("⽀付状态 ");cell = row.createCell(11);cell.setCellValue("钱包原始⾦额");cell = row.createCell(12);cell.setCellValue("钱包扣除⾦额");cell = row.createCell(13);cell.setCellValue("钱包剩余⾦额");XSSFRow rows;XSSFCell cells;for (int i = 0; i < list.size(); i++) {// 第三步:在这个sheet页⾥创建⼀⾏rows = sheet.createRow(i+1);// 第四步:在该⾏创建⼀个单元格cells = rows.createCell(0);// 第五步:在该单元格⾥设置值cells.setCellValue(list.get(i).getConsumeId());cells = rows.createCell(1);cells.setCellValue(list.get(i).getName());cells = rows.createCell(2);cells.setCellValue(list.get(i).getOrderNumber());cells = rows.createCell(3);cells.setCellValue(list.get(i).getTime());cells = rows.createCell(4);if (list.get(i).getConsumeType() == 2) {cells.setCellValue("酒⽔零⾷费");} else {cells.setCellValue("报名费");}cells = rows.createCell(5);cells.setCellValue(list.get(i).getIntegral());cells = rows.createCell(6);cells.setCellValue(list.get(i).getIntegralIn());cells = rows.createCell(7);cells.setCellValue(list.get(i).getIntegralOut());cells = rows.createCell(8);cells.setCellValue(list.get(i).getMoney());cells = rows.createCell(9);if (list.get(i).getPayment() == 2) {cells.setCellValue("积分抵现");} else if (list.get(i).getPayment() == 3) {cells.setCellValue("微信⽀付");} else if (list.get(i).getPayment() == 4) {cells.setCellValue("现⾦");} else if (list.get(i).getPayment() == 1) {cells.setCellValue("钱包");}cells = rows.createCell(10);if (list.get(i).getStatus() == 2) {cells.setCellValue("已⽀付");} else if (list.get(i).getStatus() == 1) {cells.setCellValue("未⽀付");}cells = rows.createCell(11);cells.setCellValue(list.get(i).getWalletOriginal());cells = rows.createCell(12);cells.setCellValue(list.get(i).getWalletOut());cells = rows.createCell(13);cells.setCellValue(list.get(i).getWalletSurplus());}try {OutputStream out = response.getOutputStream();wb.write(out);out.close();wb.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

java导出百万级数据到excel

java导出百万级数据到excel

java导出百万级数据到excel最近修改了⼀个导出员⼯培训课程的历史记录(⼀年数据),导出功能本来就有的,不过前台做了时间限制(只能选择⼀个⽉时间内的),还有⼀些必选条件,导出的数据⾮常有局限性。

⼼想:为什么要做出这么多条件限制呢?条件限制⽆所谓了,能限制导出数据的准确性,但是时间?如果我想导出⼀年的数据,还要⼀⽉⼀⽉的去导出,这也太扯了。

于是我试着放开时间js限制,让⽤户⾃⼰随便选好了,然后⾃⼰选了⼀段时间,选了⼏门课程,点击按钮导出,MD报错了,看后台⽇志说什么IO流报异常,看了下代码,代码也很简单,查询数据,⽤HSSFWorkbook 写⼊数据,关闭流,导出,似乎没什么问题。

于是去把查询的sql拉出来,放⼊数据库,查询数据,20w条数据,好吧,这下终于知道为什么加时间限制了,数据量过⼤程序处理不了,改代码吧。

虽说实际⼯作中很少有百万数据导⼊excel,但不缺少⼀些会excel的⾼⼿,分析对⽐数据,像我这种⼿残党是不⾏,他们怎么⽤暂时不⽤管,能不能实现,就是我们应该考虑的事了。

此案例能解决2个问题:1.⽤户导出速度过慢2.采⽤分页导出,以解决单个sheet页数据量过⼤,打开速度过慢简单介绍下我的操作:HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls,⼀张表最⼤⽀持65536⾏数据,256列,也就是说⼀个sheet页,最多导出6w多条数据XSSFWorkbook:是操作Excel2007-2010的版本,扩展名是.xlsx对于不同版本的EXCEL⽂档要使⽤不同的⼯具类,如果使⽤错了,会提⽰如下错误信息。

org.apache.poi.openxml4j.exceptions.InvalidOperationExceptionorg.apache.poi.poifs.filesystem.OfficeXmlFileException它的⼀张表最⼤⽀持1048576⾏,16384列,关于两者介绍,对下⾯导出百万数据很重要,不要使⽤错了!2.SXSSFWorkbook使⽤⽅法和 HSSFWorkbook差不多,如果你之前和我⼀样⽤的HSSFWorkbook,现在想要修改,则只需要将HSSFWorkbook改成SXSSFWorkbook即可,下⾯有我介绍,具体使⽤也可参考。

Java使用easyExcel导出excel数据案例

Java使用easyExcel导出excel数据案例

Java使⽤easyExcel导出excel数据案例easyExcel简介:Java领域解析、⽣成Excel⽐较有名的框架有Apache poi、jxl等。

但他们都存在⼀个严重的问题就是⾮常的耗内存。

如果你的系统并发量不⼤的话可能还⾏,但是⼀旦并发上来后⼀定会OOM或者JVM频繁的full gc。

easyExcel是阿⾥巴巴开源的⼀个excel处理框架,以使⽤简单、节省内存著称。

easyExcel采⽤⼀⾏⼀⾏的解析模式,并将⼀⾏的解析结果以观察者的模式通知处理easyExcel能⼤⼤减少占⽤内存的主要原因是在解析Excel时没有将⽂件数据⼀次性全部加载到内存中,⽽是从磁盘上⼀⾏⾏读取数据,逐个解析。

1.导⼊依赖【poi不能低于3.17,不然可能会报错】<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>1.1.2-beta5</version></dependency>2.控制层<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>1.1.2-beta5</version></dependency>3.导出模型package .hnezxjgl.model;import com.alibaba.excel.annotation.ExcelProperty;import com.alibaba.excel.metadata.BaseRowModel;import lombok.Data;@Datapublic class ExportModel extends BaseRowModel{/*** 账号*/@ExcelProperty(value = {"账号"}, index = 0)private String platformNum;/*** 姓名*/@ExcelProperty(value = {"姓名"}, index = 1)private String name;/*** ⾝份证号*/@ExcelProperty(value = {"⾝份证号"}, index = 2)private String idCardNum;/*** 性别*/@ExcelProperty(value = {"性别"}, index = 3)private String sexName;/*** 年级*/@ExcelProperty(value = {"年级"}, index = 4)private String gradeName;/*** 班级*/@ExcelProperty(value = {"班级"}, index = 5)private String className;/*** 学费缴费状态名称*/@ExcelProperty(value = "学费缴费状态名称",index = 6)private String studyFeeStatusName;/*** 书本费缴费状态名称*/@ExcelProperty(value = "书本费缴费状态名称",index = 7)private String bookFeeStatusName;}4.⼏万条数据实现秒导到此这篇关于Java使⽤easyExcel导出excel数据案例的⽂章就介绍到这了,更多相关Java easyExcel导出excel内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

Java导出数据生成Excel表格

Java导出数据⽣成Excel表格事先准备:⼯具类:package com.wazn.learn.util.export;import java.sql.Connection;import java.sql.DriverManager;public class DbUtil {private String dbUrl="jdbc:mysql://localhost:3306/basepro";private String dbUserName="user";private String dbPassword="user";private String jdbcName = "com.mysql.jdbc.Driver";public Connection getCon() throws Exception {Class.forName(jdbcName);Connection con = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);return con;}public void closeCon(Connection con) throws Exception {if (con != null) {con.close();}}}package com.wazn.learn.util.export;import java.sql.ResultSet;import ermodel.Row;import ermodel.Sheet;import ermodel.Workbook;public class ExcelUtil {public static void fillExcelData(ResultSet rs, Workbook wb, String[] headers) throws Exception {int rowIndex = 0; //定义⾏的初始值Sheet sheet = wb.createSheet(); //创建sheet页Row row = sheet.createRow(rowIndex++); //⾏数⾃增+1//将头信息填进单元格for (int i = 0; i < headers.length; i++) {row.createCell(i).setCellValue(headers[i]);}while (rs.next()) {row = sheet.createRow(rowIndex++); //增加⾏数System.out.println(row);for (int i = 0; i < headers.length; i++) { // 添加内容row.createCell(i).setCellValue(rs.getObject(i + 1).toString());}}}}package com.wazn.learn.util.export;import java.io.OutputStream;import java.io.PrintWriter;import javax.servlet.http.HttpServletResponse;import ermodel.Workbook;public class ResponseUtil {public static void write(HttpServletResponse response, Object o) throws Exception {response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.println(o.toString());out.flush();out.close();}public static void export(HttpServletResponse response, Workbook wb, String fileName) throws Exception{ //设置头固定格式response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "iso8859-1")); response.setContentType("text/html;charset=utf-8");OutputStream out = response.getOutputStream();wb.write(out);out.flush();out.close();}}Controller层:package com.wazn.learn.controller.teachclass;import java.sql.Connection;import java.sql.ResultSet;import javax.servlet.http.HttpServletResponse;import ermodel.HSSFWorkbook;import ermodel.Workbook;import org.apache.shiro.authz.annotation.RequiresPermissions;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import com.wazn.learn.dao.impl.ExportDao;import com.wazn.learn.util.export.DbUtil;import com.wazn.learn.util.export.ExcelUtil;import com.wazn.learn.util.export.ResponseUtil;import com.wordnik.swagger.annotations.ApiOperation;@Controller@Scope("prototype")@RequestMapping("/teach")public class ExportController {ExportDao exportDao;ExcelUtil excelUtil;@GetMapping("/page")public String stulook() {return "teach/course/export";}@SuppressWarnings("static-access")@ApiOperation(value = "导出Excel")@RequiresPermissions("upms:system:export")@RequestMapping(value = "/export", method = RequestMethod.GET)@ResponseBodypublic String export(HttpServletResponse response,String sdate,String edate) throws Exception {ExportDao exportDao = new ExportDao();DbUtil dbUtil = new DbUtil();Connection con = null;ExcelUtil excelUtil = new ExcelUtil();try {con = dbUtil.getCon();Workbook wb = new HSSFWorkbook();String headers[] = {"编号","学号","签到时间", "签到⽇期", "⽤户名","所属公司","职业"};ResultSet rs = exportDao.exportSign(con,sdate,edate);excelUtil.fillExcelData(rs, wb, headers);ResponseUtil.export( response, wb, "签到管理.xls");} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {try {dbUtil.closeCon(con);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}return null;}@SuppressWarnings("static-access")@ApiOperation(value = "导出Excel")@RequiresPermissions("upms:system:export")@RequestMapping(value = "/export2", method = RequestMethod.GET)@ResponseBodypublic String export2(HttpServletResponse response) throws Exception {ExportDao exportDao = new ExportDao();DbUtil dbUtil = new DbUtil();Connection con = null;ExcelUtil excelUtil = new ExcelUtil();try {con = dbUtil.getCon();Workbook wb = new HSSFWorkbook();String headers[] = { "签到⽇期","签到⼈数","请假⼈数"};ResultSet rs = exportDao.exportSign2(con);excelUtil.fillExcelData(rs, wb, headers);ResponseUtil.export( response, wb, "签到综合.xls");} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {try {dbUtil.closeCon(con);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}return null;}}dao层:package com.wazn.learn.dao.impl;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;public class ExportDao {public ResultSet exportSign(Connection con, String sdate, String edate) throws Exception{String sql="select s.id,u.stunum, FROM_UNIXTIME(s.signtime/1000),s.signdate,u.nickname,pany,u.job from teach_sign s join sys_user u on er_id=u.id ";if(sdate!=null&&sdate!=""){if(edate!=null&&edate!=""){sql+=" where s.signdate>='"+sdate+"' and s.signdate<='"+edate+"' ";}else{sql+=" where s.signdate>='"+sdate+"' ";}}else{if(edate!=null&&edate!=""){sql+=" where s.signdate<='"+edate+"' ";}else{}}StringBuffer sb = new StringBuffer(sql);PreparedStatement pstmt = con.prepareStatement(sb.toString());return pstmt.executeQuery();}public ResultSet exportSign2(Connection con) throws Exception{String sql="select signdate as signdate, count(distinct user_id)-count(leave1) as countuser,count(leave1) as countleave from teach_signs group by signdate";StringBuffer sb = new StringBuffer(sql);PreparedStatement pstmt = con.prepareStatement(sb.toString());return pstmt.executeQuery();}}前台页⾯:两个不同的,传参数根据⽇期和不传参数<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%><%@ pageimport="org.springframework.security.core.context.SecurityContextHolder"%><%@ page import="com.wazn.learn.configure.security.CustomerUser"%><%String basePath = request.getContextPath();CustomerUser user = (CustomerUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>选择导出⽇期</title><script type="text/javascript"src="<%=basePath%>/res/js/jquery-1.12.4.min.js"></script><script src="<%=basePath%>/res/layui/layui.js" charset="utf-8"></script><link rel="stylesheet" href="<%=basePath%>/res/layui/css/layui.css"media="all"></head><style type="text/css"></style><body class="gray-bg"><div class="layui-form-item "><label class="layui-form-label">开始⽇期:</label><div class="layui-input-block"><input type="text" class="layui-input" placeholder="请选择开始时间" id="sdate1" name="sdate1"></div></div><div class="layui-form-item"><label class="layui-form-label">结束⽇期:</label><div class="layui-input-block"><input type="text" class="layui-input" placeholder="请选择截⽌时间" id="edate1" name="edate1"></div></div><div class="layui-input-block"><a class="waves-effect waves-button" href="javascript:;" onclick="exportAction()"><button class="layui-btn" style="transform: translateY(-3px);" data-type="reload">导出签到表格</button></a></div><script>//导出Excel⽂件function exportAction(){var s = $('#sdate1').val();var e = $('#edate1').val();var str="sdate='"+s+"'&&edate='"+e+"'";window.open("<%=basePath%>/teach/export?sdate="+s+"&&edate="+e+" ");}e(['table','form','laydate'], function(){var table = layui.table,form = layui.form,laydate = ydate;;laydate.render({elem: '#sdate1',type: 'date'});laydate.render({elem: '#edate1',type: 'date'});});</script></body></html><%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%><%@ page import="org.springframework.security.core.context.SecurityContextHolder"%><%@ page import="com.wazn.learn.configure.security.CustomerUser"%><%String basePath = request.getContextPath();CustomerUser user = (CustomerUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><script type="text/javascript" src="<%=basePath%>/res/js/jquery-1.12.4.min.js"></script><script src="<%=basePath%>/res/layui/layui.js" charset="utf-8"></script><link rel="stylesheet" href="<%=basePath%>/res/layui/css/layui.css" media="all"><title>数据报表</title></head><body><div style="margin: 0px; background-color: white; margin: 0 10px;"><blockquote class="layui-elem-quote" style="height: 45px"><div class="layui-col-md2"><a class="waves-effect waves-button" href="javascript:;" onclick="exportAction()"><button class="layui-btn" style="transform: translateY(-3px);" data-type="reload">导出签到表格</button></a></div></blockquote></div><table class="layui-table"lay-data="{url:'<%=basePath%>/teach/course/getsignreport', page:true, id:'idTest', limit: 10,limits: [10,20,30]}"lay-filter="demo"><thead><tr><th lay-data="{field:'signdate', width:'30%',align:'center', sort: true}">签到⽇期</th><th lay-data="{field:'user', width:'30%',align:'center',toolbar: '#bar1'}">签到⼈数</th><th lay-data="{field:'leave', width:'30%',align:'center' ,toolbar: '#bar2'}">请假⼈数</th></tr></thead></table><script>//导出Excel⽂件function exportAction(){window.open("<%=basePath%>/teach/export2");}</script><script type="text/html" id="bar1"><a class="layui-btn layui-btn-primary layui-btn-xs" id="test" lay-event="sign">{{d.countuser}}</a></script><script type="text/html" id="bar2"><a class="layui-btn layui-btn-primary layui-btn-xs" id="test" lay-event="leave">{{d.countleave}}</a></script><script>e(['table','form','laydate','layer'], function(){var table = layui.table,form = layui.form,layer=yer,laydate = ydate;;laydate.render({elem: '#edate',type: 'datetime'});laydate.render({elem: '#sdate',type: 'datetime'});laydate.render({elem: '#sdate1',type: 'date'});laydate.render({elem: '#edate1',type: 'date'});//监听⼯具条table.on('tool(demo)', function(obj){var data = obj.data;if(obj.event === 'sign'){layer.open({title : "签到详情",type : 2,area: ['70%', '80%'],content : "<%=basePath%>/teach/course/signlook?leave=0&date="+data.signdate,})}else if(obj.event==='leave'){layer.open({title : "请假详情",type : 2,area: ['80%', '80%'],content : "<%=basePath%>/teach/course/signlook?leave=1&date="+data.signdate, })}});var $ = layui.$, active = {reload: function(){var demoReload = $('#demoReload');//执⾏重载table.reload('idTest', {page: {curr: 1 //重新从第 1 页开始},where: {name: demoReload.val(),sdate:$('#sdate').val(),edate:$('#edate').val()}});}};$('.demoTable .layui-btn').on('click', function(){var type = $(this).data('type');active[type] ? active[type].call(this) : '';});});</script></body></html>。

java实现导出Excel(跨行,跨列)

java实现导出Excel(跨⾏,跨列)先来个最终结果样式:第⼀步:传参,后期可根据⾃⼰需要进⾏调整。

我这⾥需要的是quarter 代表季度dptid 部门编号根据接受过来的参数进⾏⽂档命名。

UserInfo userInfo=(UserInfo)request.getSession().getAttribute("userInfo");String userid=userInfo.getUserID();String quarter = request.getParameter("quarter");String dptid = request.getParameter("dptid");/***********************EXCEL导出部分**************************/String str3 = FileInfoTools.getSystemFilePath()+ "/documentTemp/";File file = new File(str3);if (!file.exists() && !file.isDirectory()) {file.mkdir();}String names = new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date());String ourl = str3 + names + "_"+userid+".xls";FileOutputStream fos = null;String fileName = "";try {HSSFWorkbook wb = new HSSFWorkbook();//创建⼯作薄fileName = "安全可控导出"+"_"+userid+"_"+names+".xls";DBManager dbm = new DBManager();System.out.println("quarter+"+quarter+"dptid="+dptid);try{dbm.newConnection();String str = "select departmentname from dpt_department where departmentid='"+dptid+"'"; //获取唯⼀idString dptName = dbm.executeQueryString(str);fileName=dptName+"部门安全可控清单汇总"+"_"+userid+"_"+names+".xls";//创建sheet页,并写⼊内容createSheet(dbm,wb,getCardInfo(dbm,quarter,dptid));}catch(Exception e){e.printStackTrace();}finally{dbm.closeConnection();}File ff = new File(ourl);if (ff.exists()) {ff.delete();}fos = new FileOutputStream(ourl);wb.write(fos);fos.close();String u = "/project/system/fileAction.do?filePath=" + URLEncoder.encode(ourl)+ "&fileName=" + URLEncoder.encode(fileName);response.sendRedirect(u);} catch (Exception e) {e.printStackTrace();}第⼆步:创建sheet页签public void createSheet(DBManager dbm,HSSFWorkbook w,Vector vt) throws Exception{for(int i=0;i<vt.size();i++){Hashtable ht = (Hashtable)vt.get(i);String id = (String)ht.get("id");String quarter = (String)ht.get("quarter");HSSFSheet sheet = w.createSheet("安全可控清单");//写⼊数据wirteSheet(dbm,sheet,w,id,quarter);}}我这⾥页签是固定的名称可根据⾃⼰的需要根据参数来进⾏判断页签。

关于Java中excel表格导出的总结(Java程序导出模板和Java根据模板导出表格两种。。。

关于Java中excel表格导出的总结(Java程序导出模板和Java根据模板导出表格两种。

导出excel通⽤模板(程序定义模板导出)转载原⽂:如下代码,本⽅法主要⽤于程序定义模板格式,并导出⽂件。

该⽅法将定义和创建分离,达到了⼀定解耦合,降低了开发复杂度。

但是依然是程序定义模板,对模板的样式需要程序控制,没有达到将数据和样式分离的⽬的。

改良版,关于添加依赖之类的之前⼀篇⽂章⾥⾯有。

这篇是把之前的⽅法抽成通⽤模板。

⼀、添加⼀个实体类package com.lencity.securitymanagementplatform.data.entity;import java.util.List;public class XlsData {public static final int DATA_TYPE_INTEGER = 0;public static final int DATA_TYPE_STRING = 1;private List<String> titles;//表头private List<Integer> types;//数据类型private List<List<Object>> values;存表数据public List<Integer> getTypes() {return types;}public void setTypes(List<Integer> types) {this.types = types;}public List<String> getTitles() {return titles;}public void setTitles(List<String> titles) {this.titles = titles;}public List<List<Object>> getValues() {return values;}public void setValues(List<List<Object>> values) {this.values = values;}}⼆、创建⼀个service类package com.lencity.securitymanagementplatform.service;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import .URLEncoder;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import ermodel.HSSFCell;import ermodel.HSSFCellStyle;import ermodel.HSSFDataFormat;import ermodel.HSSFFont;import ermodel.HSSFRow;import ermodel.HSSFSheet;import ermodel.HSSFWorkbook;import ermodel.HorizontalAlignment;import org.springframework.stereotype.Service;import com.lencity.securitymanagementplatform.data.entity.XlsData;@Servicepublic class XlsService {//写⼀个接⼝,哪个控制器需要加上导出excel功能就继承这个接⼝public static interface IXlsOutputProcessor {public XlsData processXlsData(Map<String, Object> condition);}//解析数据创建excelpublic HSSFWorkbook createExcelData(IXlsOutputProcessor processor, Map<String, Object> condition) {XlsData xlsData = processor.processXlsData(condition);HSSFWorkbook workbook = new HSSFWorkbook();HSSFSheet sheet = workbook.createSheet("统计表");// 创建⼀个excel表单HSSFRow titleRow = sheet.createRow(0);// 设置列宽,setColumnWidth的第⼆个参数要乘以256,这个参数的单位是1/256个字符宽度sheet.setColumnWidth(1, 15 * 256);sheet.setColumnWidth(3, 20 * 256);HSSFCellStyle style = workbook.createCellStyle();style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));// 设置⽇期格式HSSFFont font = workbook.createFont();// 设置为居中加粗font.setBold(true);style.setAlignment(HorizontalAlignment.CENTER);style.setFont(font);List<String> titles = xlsData.getTitles();HSSFCell cell;/* 构造表头 */for (int i = 0; i < titles.size(); i++) {cell = titleRow.createCell(i);cell.setCellValue(titles.get(i));cell.setCellStyle(style);}int rowNum = 1;List<Integer> dataTypes = xlsData.getTypes();List<List<Object>> values = xlsData.getValues();for (int i = 0; i < values.size(); i++) {List<Object> value = values.get(i);HSSFRow row = sheet.createRow(rowNum);for (int j = 0; j < value.size(); j++) {switch (dataTypes.get(j)) {case XlsData.DATA_TYPE_INTEGER:row.createCell(j).setCellValue((Integer) value.get(j));break;case XlsData.DATA_TYPE_STRING:row.createCell(j).setCellValue((String) value.get(j));break;}}rowNum++;}return workbook;}// 浏览器导出excelpublic void buildExcelDocument(String filename, HSSFWorkbook workbook, HttpServletResponse response)throws Exception {response.reset();response.setContentType("application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8")); OutputStream outputStream = response.getOutputStream();workbook.write(outputStream);outputStream.flush();outputStream.close();}// 下载excel模板功能public void downloadTemplate(HttpServletResponse response,HttpServletRequest request) throws Exception {String fileName="导出模板.xls";response.reset();response.setContentType("application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8")); String filePath=request.getServletContext().getRealPath("/excel/")+fileName;FileInputStream input=new FileInputStream(filePath);OutputStream out=response.getOutputStream();byte[] b=new byte[2048];int len;while((len=input.read(b))!=-1) {out.write(b,0,len);}response.setHeader("Content-Length", String.valueOf(input.getChannel().size()));input.close();}}三、控制器假设我们要在⽤户页⾯加上导出表格的功能,那就在⽤户的控制器上继承接⼝public class UserController implements IXlsOutputProcessor {继承之后需要在控制器中重写接⼝⽅法,导出的表格样式.png关于封装数据,主要就是根据⾃⼰实际的项⽬需求,来构造数据了// 封装数据@Overridepublic XlsData processXlsData(Map<String, Object> condition) {List<String> titles = new ArrayList<>();//表头List<Integer> dataTypes = new ArrayList<>();//表数据类型List<List<Object>> values = new ArrayList<>();//表头对应的数据titles.add("姓名");dataTypes.add(XlsData.DATA_TYPE_STRING);titles.add("⼿机号码");dataTypes.add(XlsData.DATA_TYPE_STRING);titles.add("职位");dataTypes.add(XlsData.DATA_TYPE_STRING);titles.add("部门");dataTypes.add(XlsData.DATA_TYPE_STRING);List<User> users = userService.getUsersByCondition(condition);XlsData xlsData = new XlsData();xlsData.setTitles(titles);xlsData.setTypes(dataTypes);for (User user : users) {List<Object> tmpList = new ArrayList<>();tmpList.add(user.getName());tmpList.add(user.getMobile());tmpList.add(user.getPosition());tmpList.add(departmentService.getDepartmentNameByDepartmentCode(user.getDepartmentCode()));values.add(tmpList);}xlsData.setValues(values);return xlsData;}// 导出excel,前台js,点击导出excel 关联的路径就是这个@PostMapping(value = "/downLoadXls")@ResponseBodypublic String downLoadXls(Map<String, Object> condition, HttpServletResponse response) throws Exception { String fileName = "导出excel.xls";HSSFWorkbook workbook = xlsService.createExcelData(this, condition);xlsService.buildExcelDocument(fileName, workbook, response);JSONObject jsonObject = new JSONObject();jsonObject.put("code", 1);return jsonObject.toString();}// 下载模板,前台js,点击下载模板关联的路径就是这个@PostMapping(value = "/downloadTemplate")@ResponseBodypublic String downloadTemplate(HttpServletResponse response,HttpServletRequest request) throws Exception { String fileName = "导出excel.xls";xlsService.downloadTemplate(response, request);JSONObject jsonObject = new JSONObject();jsonObject.put("code", 1);return jsonObject.toString();}前台界⾯.png模板的存放位置前台按钮代码<button type="button" class="btn btn-primary waves-effect" onclick="downloadTemplate()" id="downloadTemplate"><i class="material-icons">vertical_align_bottom</i><span>下载模板</span></button><button type="button" class="btn btn-primary waves-effect"onclick="exportExcel()"><i class="material-icons">vertical_align_bottom</i><span>导出表格</span></button>jsform表单⾥⾯是页⾯的表单筛选条件,如果要导数据库所有的数据,可把form表单去掉。

记一次Java导出大批量Excel优化

记⼀次Java导出⼤批量Excel优化常⽤的excel导出⽅案,详情见,其中jxl、esayEscel 底层都是基于 poi,它们仅仅是对 poi 进⾏了封装,使导出 excel 的代码更加简洁(封装poi,导出 excel 的⼯具类有很多,jxl 和 esayExcel 使⽤的⽐较多)。

所以,如果遇到 excel 导出效率低下,直接基于 poi 导出 Excel,效率肯定是最⾼的,只是代码⽐较繁琐与杂乱。

我主要是基于 esayExcel (⽬前使⽤⽐较多),对其 api 进⾏衍⽣与应⽤,解决导出⼤量 Excel 导致的 OOM,或者数据超界异常:ng.IllegalArgumentException: Invalid row number (1048576) outside allowable range (0..1048575)应⽤是基于100W条数据进⾏的测试,数据的获取代码如下1package bean;23import com.alibaba.excel.annotation.ExcelProperty;4import com.alibaba.excel.annotation.format.DateTimeFormat;5import com.alibaba.excel.annotation.format.NumberFormat;6import lombok.Data;7import lombok.experimental.Accessors;89import java.util.Date;1011/**12 * @author dz13 * @date 2021-11-06 上午 9:1414*/15 @Accessors(chain = true)16 @Data17public class ExcelBean {1819 @ExcelProperty("主键id")20private String id;2122 @ExcelProperty("姓名")23private String name;2425 @ExcelProperty("地址")26private String address;2728 @ExcelProperty("年龄")29private Integer age;3031 @ExcelProperty("数量")32private Integer number;3334 @NumberFormat("#.##")35 @ExcelProperty("⾝⾼")36private Double high;3738 @ExcelProperty("距离")39private Double distance;4041 @DateTimeFormat("yyyy-MM-dd HH:mm:ss")42 @ExcelProperty("开始时间")43private Date startTime;4445 @ExcelProperty("结束时间")46private Date endTime;47 }1/**2 * 获取excel 导出的数据3 *4 * @return list 集合5*/6private List<ExcelBean> getDate() {7 ("开始⽣成数据");8 Date date = new Date();9long startTime = System.currentTimeMillis();10 List<ExcelBean> list = Lists.newArrayList();11for (int i = 0; i < 1000000; i++) {12 ExcelBean bean = new ExcelBean();13 bean.setId(UUID.randomUUID().toString()).14 setName("隔壁⽼樊" + i).15 setAddress("北京市朝阳区酒仙桥" + i + "路").16 setAge(i).17 setNumber(i + 10000).18 setHigh(1.234 * i).19 setDistance(1.234 * i).20 setStartTime(date).21 setEndTime(date);22 list.add(bean);23 }24 ("数据⽣成结束,数据量={},耗时={}ms", list.size(), System.currentTimeMillis() - startTime);25return list;26 }pom 依赖1<dependency>2<groupId>org.projectlombok</groupId>3<artifactId>lombok</artifactId>4</dependency>5<dependency>6<groupId>com.alibaba</groupId>7<artifactId>easyexcel</artifactId>8<version>2.2.10</version>9</dependency>依赖 esayexcel 时,如果项⽬已经依赖了 poi,有可能会产⽣jar 包依赖冲突(easyexcel底层也是基于 poi),解决⽅案如下:⽅案⼀:查看 easyexcel 中依赖的 poi 的版本,然后将项⽬其余地⽅的版本修改成该版本,使项⽬依赖的 poi 版本和 easyexcel 依赖的版本⼀致⽅案⼆:在 esayexcel 中将 poi 的依赖排除掉,如下<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.10</version><exclusions><exclusion><groupId>org.apache.poi</groupId><artifactId>poi</artifactId></exclusion><exclusion><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId></exclusion><exclusion><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId></exclusion></exclusions></dependency>常量的定义1public static final String FILE_NAME = "D:\\test_" + System.currentTimeMillis() + ".xlsx";2// 每个 sheet 写⼊的数据3public static final int NUM_PER_SHEET = 300000;4// 每次向 sheet 中写⼊的数据(分页写⼊)5public static final int NUM_BY_TIMES = 50000;1.EasyExcel 导出 excel 应⽤使⽤ esayExcel ⾃带的 api 导出 excel 的应⽤,代码如下1/**2 * ⽅法⼀:将数据写⼊到excel3 * 直接调⽤api,适合⼩数据量4 * 100W条数据33s5*/6 @Test7public void writeExcelByApi() {8 String fileName = FILE_NAME;9 ("导出excel名称={}", fileName);10long startTime = System.currentTimeMillis();11// 直接调⽤api12 List<ExcelBean> date = getDate();13 EasyExcel.write(fileName, ExcelBean.class).sheet().doWrite(date);14 ("导出excel结束,数据量={},耗时={}ms", date.size(), System.currentTimeMillis() - startTime);15 }当 list 对象数据量太多,就会产⽣异常:原因是单个 excel ⼀个 sheet 的最⼤数据量为 10485751 ng.IllegalArgumentException: Invalid row number (1048576) outside allowable range (0..1048575)23 at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:123)4 at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:65)5 at com.alibaba.excel.util.WorkBookUtil.createRow(WorkBookUtil.java:70)6 at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addOneRowOfDataToExcel(ExcelWriteAddExecutor.java:67)7 at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.add(ExcelWriteAddExecutor.java:56)8 at com.alibaba.excel.write.ExcelBuilderImpl.addContent(ExcelBuilderImpl.java:58)9 at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:161)10 at com.alibaba.excel.ExcelWriter.write(ExcelWriter.java:146)11 at com.alibaba.excel.write.builder.ExcelWriterSheetBuilder.doWrite(ExcelWriterSheetBuilder.java:61)12 at mytest.TestExcel.writeExcelByApi(TestExcel.java:40)13 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)14 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)15 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)16 at ng.reflect.Method.invoke(Method.java:498)17 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)18 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)19 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)20 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)21 at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)22 at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)23 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)24 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)25 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)26 at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)27 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)28 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)29 at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)30 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)31 at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)32 at org.junit.runners.ParentRunner.run(ParentRunner.java:413)33 at org.junit.runner.JUnitCore.run(JUnitCore.java:137)34 at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)35 at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)36 at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)37 at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)2.EasyExcel 导出 excel 应⽤优化⼀:execl 数据量超过1048575将数据写⼊到不同的 sheet,保证每个 sheet 的数据量⼩于 1048575 ⾏,解决此问题,代码如下1/**2 * ⽅法⼆:导出多个sheet3 * easyExcel 底层是 POI 实现的,POI 单个sheet 最多只能导出 1048576 ⾏,超过该⾏数,会产⽣如下异常4 * ng.IllegalArgumentException: Invalid row number (1048576) outside allowable range (0..1048575)5 * <p>6 * 11:57:55.541 [main] INFO mytest.TestExcel - 写⼊sheet=sheet0,数据量300000-0=300000,耗时=6055ms7 * 11:57:59.701 [main] INFO mytest.TestExcel - 写⼊sheet=sheet1,数据量600000-300000=300000,耗时=4159ms8 * 11:58:03.827 [main] INFO mytest.TestExcel - 写⼊sheet=sheet2,数据量900000-600000=300000,耗时=4126ms9 * 11:58:05.193 [main] INFO mytest.TestExcel - 写⼊sheet=sheet3,数据量1000000-900000=100000,耗时=1366ms10 * 11:58:17.418 [main] INFO mytest.TestExcel - 导出excel结束,总数据量=1000000,耗时=31297ms11*/12 @Test13public void writeExcelByMulSheet() {14 String fileName = FILE_NAME;15 ("导出excel名称={}", fileName);16long startTime = System.currentTimeMillis();17// 获取数据18 List<ExcelBean> date = getDate();19// 获取 sheet 的个数20int sheetNum = date.size() % NUM_PER_SHEET == 0 ? date.size() / NUM_PER_SHEET : date.size() / NUM_PER_SHEET + 1;21// 指定写⼊的⽂件22 ExcelWriter excelWriter = EasyExcel.write(fileName, ExcelBean.class).build();23for (int i = 0; i < sheetNum; i++) {24long l = System.currentTimeMillis();25// 设置 sheet 的名字(sheet不能相同)26 String sheetName = "sheet" + i;27 WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetName).build();28int startNum = i * NUM_PER_SHEET;29int endNum = i == sheetNum - 1 ? date.size() : (i + 1) * NUM_PER_SHEET;30 excelWriter.write(date.subList(startNum, endNum), writeSheet);31 ("写⼊sheet={},数据量{}-{}={},耗时={}ms", sheetName, endNum, startNum, endNum - startNum, System.currentTimeMillis() - l);32 }33// 最好放在 finally中34 excelWriter.finish();35 ("导出excel结束,总数据量={},耗时={}ms", date.size(), System.currentTimeMillis() - startTime);36 }3.EasyExcel 导出 excel 应⽤优化⼆:数据源 list 太⼤,直接读取全部的 list 数据导致 OOM将 list 数据进⾏分页读取,并进⾏分页写⼊到 excel。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档