java接口返回文件_根据接口文档书写接口,并在前端调用接口返回显示出数据(加下载)...

该博客详细介绍了如何使用Apache POI库创建一个高效的大数据量Excel导出工具。通过设置最大行数、分页行数和SXSSF缓存行数,实现了内存管理和分页导出。内容包括设置内容总数、标题和表头,以及遍历分页列表写入内容。此外,还展示了如何设置单元格样式、自适应列宽、合并单元格和处理大文件时的内存优化。
摘要由CSDN通过智能技术生成

1 packagecom.eptok.util;2

3 importjava.io.ByteArrayOutputStream;4 importjava.io.FileOutputStream;5 importjava.io.IOException;6 importjava.io.OutputStream;7 importjava.io.UnsupportedEncodingException;8 importjava.math.BigDecimal;9 importjava.text.DecimalFormat;10 importjava.util.ArrayList;11 importjava.util.HashMap;12 importjava.util.List;13 importjava.util.Map;14

15 importjavax.servlet.http.HttpServletResponse;16

17 importorg.apache.poi.hssf.util.HSSFColor;18 importorg.apache.poi.ss.usermodel.Cell;19 importorg.apache.poi.ss.usermodel.CellStyle;20 importorg.apache.poi.ss.usermodel.Font;21 importorg.apache.poi.ss.usermodel.HorizontalAlignment;22 importorg.apache.poi.ss.usermodel.Row;23 importorg.apache.poi.ss.usermodel.Sheet;24 importorg.apache.poi.ss.usermodel.VerticalAlignment;25 importorg.apache.poi.ss.util.CellRangeAddress;26 importorg.apache.poi.xssf.streaming.SXSSFSheet;27 importorg.apache.poi.xssf.streaming.SXSSFWorkbook;28

29 importhikefa.core.web.page.Pager;30

31 public classExportExcle {32

33 /**最大导出行数*/

34 public static final int MAX_ROWS = 500000;35

36 /**分页行数*/

37 public static final int PAGING_ROWS = 50000;38

39 /**SXSSF操作行数*/

40 public static final int SXSSF_ROWS = 100;41

42 /**缓存行数*/

43 public static final int CACHE_ROWS = 1000;44

45 /**创建Workbook*/

46 SXSSFWorkbook workbook = newSXSSFWorkbook(SXSSF_ROWS);47

48 /**当前Sheet*/

49 Sheet sheet;50

51 /**内容总数*/

52 private int contentCount = 0;53

54 /**总页数*/

55 private intpageCount;56

57 /**分页列表*/

58 private List pagerList = new ArrayList<>();59

60 /**标题*/

61 privateString title;62

63 /**表头数组*/

64 privateObject[][] headerArray;65

66 /**导出列数*/

67 private intcolCount;68 /**标题行数*/

69 private int titleRows = 0;70 /**标题行数*/

71 private int headerRows = 0;72

73 /**样式Map*/

74 private Map styleMap = new HashMap<>();75

76 /**列宽数组*/

77 privateInteger[] intArray;78

79 /**构造方法*/

80 publicExportExcle() {81 }82 // //***Demo***83 //ExportExcle exportExcle = new ExportExcle();//新建导出对象84 //int contentCount = 0;//从数据库获取内容总数(可选)----------step_0(数据量大于50000,建议设置)85 //exportExcle.setContentCount(contentCount);//设置内容总数(可选)----------step_0(数据量大于50000,建议设置)86 //Object[] headerArray = new Object[] {//表头数组87 //"",88 //""};89 //exportExcle.setTitleAndHeader("标题", headerArray);//设置标题和表头----------step_190 // //遍历分页列表进行操作91 //for(Pager pager : exportExcle.getPagerList()) {92 //List contentList = new ArrayList<>();//内容列表93 // //---------- 将从数据库获取的数据封装成List开始94 //Paginater paginater = server.findSplitPage(pager);95 //for(Object object : paginater.getData()) {96 //Map map = (Map) object;97 //Object[] objArr = new Object[] {};98 //contentList.add(objArr);//增加内容99 //}100 // //---------- 将从数据库获取的数据封装成List结束101 //exportExcle.setContentPagerDate(contentList, pager);//设置需要导出的内容列表----------step_2102 //}103 //exportExcle.exportWorkbook(response);//将文件写入输出流----------step_3

104

105

106 /**step_0:设置内容总数(不设置则默认为单页导出)*/

107 public void setContentCount(intcontentCount) {108 this.contentCount = contentCount; //设置内容总数

109 }110

111 /**step_1:设置标题和表头数组(单行),并初始化参数*/

112 public voidsetTitleAndHeader(String title, Object[] headerArray) {113 Object[][] headerArrayTemp = new Object[1][];114 headerArrayTemp[0] =headerArray;115 setTitleAndHeader(title, headerArrayTemp);116 }117 /**step_1:设置标题和表头数组(多行),并初始化参数*/

118 public voidsetTitleAndHeader(String title, Object[][] headerArray) {119 this.title =title;120 this.headerArray =headerArray;121 parameterChecking(); //校验参数

122 }123

124 /**step_2:设置需要导出的内容列表*/

125 public void setContentPagerDate(ListcontentList, Pager pager) {126 LogUtil.APP.info("开始将[" + title + "] - 第" + pager.getPageNumber() +"页数据写入Excle文件 - "

127 + DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));128 if(null == contentList ||contentList.isEmpty()) {129 throw new IllegalArgumentException("查询不到需要导出的数据[contentList]");130 }131 //---------- 导出数据到Excle文件Sheet页开始

132 String sheetName = "第" + pager.getPageNumber() +"页 - 共" + pageCount + "页"; //sheet名称

133 sheet = workbook.createSheet(sheetName); //创建工作表

134 writeTitle(); //写入标题

135 writeHeader(); //写入表头数组

136 writeContent(contentList); //写入内容列表

137 autoColumnSize(); //自适应列宽,并冻结窗格138 //---------- 导出数据到Excle文件Sheet页结束

139 contentList.clear(); //清空列表

140 LogUtil.APP.info("将[" + title + "] - 第" + pager.getPageNumber() +"页数据写入Excle文件结束 - "

141 + DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));142 }143

144 /**step_3:将文件写入输出流*/

145 public voidexportWorkbook() {146 exportWorkbook("D:/"); //默认导出到D盘根目录

147 }148 /**step_3:将文件写入输出流*/

149 public voidexportWorkbook(String path) {150 FileOutputStream fos = null;151 try{152 fos = new FileOutputStream(path + title + ".xlsx");153 workbook.write(fos);154 ((SXSSFWorkbook) workbook).dispose();155 } catch(IOException e) {156 e.printStackTrace();157 } finally{158 if (fos != null) {159 try{160 fos.close();161 } catch(IOException e) {162 e.printStackTrace();163 }164 }165 }166 }167 /**step_3:将文件写入输出流*/

168 public voidexportWorkbook(HttpServletResponse response) {169 ByteArrayOutputStream baos = null;170 OutputStream os = null;171 try{172 baos = newByteArrayOutputStream();173 workbook.write(baos);174 ((SXSSFWorkbook) workbook).dispose();175 String fileName = new String(title.getBytes("gbk"), "ISO8859-1");176 response.reset(); //清空输出流

177 response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");178 response.setContentType("application/msexcel");179 response.setContentLength(baos.size());180 os =response.getOutputStream();181 baos.writeTo(os);182 os.flush();183 } catch(IOException e) {184 e.printStackTrace();185 } finally{186 if (baos != null) {187 try{188 baos.close();189 } catch(IOException e) {190 e.printStackTrace();191 }192 }193 if (os != null) {194 try{195 os.close();196 } catch(IOException e) {197 e.printStackTrace();198 }199 }200 }201 }202

203

204 //--------------------------------------------------调用的方法--------------------------------------------------

205

206

207 /**校验参数*/

208 private voidparameterChecking() {209 if(null ==title) {210 throw new IllegalArgumentException("标题未设置");211 }212 if(null == headerArray || headerArray.length == 0) {213 throw new IllegalArgumentException("表头数组未设置");214 } else{215 if(null != headerArray[0] && 0 < headerArray[0].length) {216 headerRows = headerArray.length; //设置表头行数

217 colCount = headerArray[0].length; //设置导出列数

218 intArray = new Integer[colCount]; //初始化列宽数组

219 } else{220 throw new IllegalArgumentException("无法确定导出列数");221 }222 }223 if(contentCount <= 0) {224 contentCount = PAGING_ROWS; //默认为单页导出

225 }226 setPagerList(); //设置分页信息

227 initStyleMap(); //初始化样式Map

228 }229

230 /**设置分页列表*/

231 private voidsetPagerList() {232 if(contentCount >MAX_ROWS) {233 contentCount =MAX_ROWS;234 }235 //计算总页数

236 pageCount = contentCount % PAGING_ROWS > 0 ? contentCount / PAGING_ROWS + 1 : contentCount /PAGING_ROWS;237 //设置分页列表

238 for (int i = 1; i <= pageCount; i++) {239 //int paging = i == pageCount && contentCount % PAGING_ROWS > 0 ?240 //contentCount % PAGING_ROWS : PAGING_ROWS;//当前分页行数241 //pagingList.add(i, new Pager(i, paging));

242 pagerList.add(newPager(i, PAGING_ROWS));243 }244 }245 /**获取分页列表*/

246 public ListgetPagerList() {247 returnpagerList;248 }249

250

251 //--------------------------------------------------Excle操作--------------------------------------------------

252

253

254 /**写入表头标题*/

255 private voidwriteTitle() {256 //创建行对象

257 Row row = sheet.createRow(0); //创建行对象

258 Cell cell = row.createCell(0); //创建单元格

259 cell.setCellValue(title); //写入内容

260 setRowStyle(0, styleMap.get("titleStyle")); //设置行样式

261 mergedRegion(0, 0, 0, colCount-1); //合并单元格

262 titleRows = 1; //记录标题行数

263 }264

265 /**写入表头数组headerArray[row][col]*/

266 private voidwriteHeader() {267 for(int rowNum=0; rowNum < headerRows; rowNum++) {268 if(null == headerArray[rowNum] || 0 ==headerArray[rowNum].length) {269 continue; //行数据为空,跳出当次循环

270 }271 //创建行对象

272 Row row = sheet.createRow(rowNum +titleRows);273 for(int colNum=0; colNum < colCount; colNum++) {274 Cell cell = row.createCell(colNum); //创建单元格

275 cell.setCellStyle(styleMap.get("headerStyle")); //设置表头样式

276 if(null == headerArray[rowNum][colNum] || "*".equals(headerArray[rowNum][colNum])) {277 continue; //单元格数据为空,跳出当次循环

278 }279 setCellValue(cell, headerArray[rowNum][colNum], colNum); //写入内容值

280 }281 }282 }283

284 /**写入内容列表contentList*/

285 private void writeContent(ListcontentList) {286 for(int rowNum = 0; rowNum < contentList.size(); rowNum++) {287 Object[] array =contentList.get(rowNum);288 if(null == array || 0 ==array.length) {289 continue; //数组为空,跳出当次循环

290 }291 //创建行对象

292 Row row = sheet.createRow(rowNum + titleRows + titleRows); //在表头之后

293 for(int colNum = 0; colNum < array.length; colNum++) {294 if(null ==array[colNum]) {295 continue; //跳出当次循环

296 }297 Cell cell = row.createCell(colNum); //创建单元格

298 cell.setCellStyle(styleMap.get("contentStyle")); //设置样式

299 setCellValue(cell, array[colNum], colNum); //写入内容值

300 }301 //每当行数达到设置的值就刷新数据到硬盘,以清理内存

302 if(rowNum % CACHE_ROWS == 0){303 try{304 ((SXSSFSheet) sheet).flushRows();305 } catch(IOException e) {306 e.printStackTrace();307 }308 }309 }310 autoMergedRegion(); //自动合并单元格

311 }312

313 /**自适应列宽*/

314 private voidautoColumnSize() {315 /*//自适应列宽316 for(int colNum=0; colNum

324 //批量设置列宽

325 for(int i=0; i

328 intArray[i] =sheet.getDefaultColumnWidth();329 }330 sheet.setColumnWidth(i, (int)((intArray[i] + 2 + 0.72) * 256)); //参数为列index,列宽(字符数)

331 }332 //冻结窗格

333 sheet.createFreezePane(0, titleRows + headerRows, 0, titleRows +headerRows);334 }335

336

337

338 /**设置单元格的值*/

339 private void setCellValue(Cell cell, Object obj, intcolNum) {340 //格式化参数

341 if(obj instanceof BigDecimal || obj instanceofDouble) {342 Double decimal = Double.valueOf(obj.toString().replace(" ", ""));343 obj = new DecimalFormat("#0.00").format(decimal);344 }345 cell.setCellValue(obj.toString()); //写入内容

346 try{347 int length = obj.toString().getBytes("gbk").length;348 if(intArray[colNum] == null || intArray[colNum]

356 /**自动合并单元格*/

357 private voidautoMergedRegion() {358 if(null == headerArray || 0 ==headerArray.length) {359 return; //表头数组为空,退出方法

360 }361 if(null == headerArray[0][0]) {362 headerArray[0][0] = ""; //初始项不能空

363 }364 //设置表头数值

365 for(int rowNum=0; rowNum < headerRows; rowNum++) {366 for(int colNum=0; colNum < colCount; colNum++) {367 if(null != headerArray[rowNum][colNum] && !"*".equals(headerArray[rowNum][colNum])) {368 autoMergedRegion(rowNum ,colNum); //执行合并操作

369 }370 }371 }372 }373 /**执行合并操作*/

374 private void autoMergedRegion(int firstRow ,intfirstCol) {375 int lastRow = headerRows - 1; //最后一行

376 int lastCol = colCount - 1; //最后一列377 //如果不为最后一行

378 if(firstRow !=lastRow) {379 for(int row = firstRow+1; row < headerRows; row++) {380 if(null !=headerArray[row][firstCol]) {381 if("*".equals(headerArray[row][firstCol])) {382 lastRow = row; //定位最后一行,占位符不减1

383 } else{384 lastRow = row-1; //定位最后一行

385 }386 break;387 }388 }389 }390 //如果不为最后一列

391 if(firstCol !=lastCol) {392 for(int col=firstCol+1; col < colCount; col++) {393 if(null !=headerArray[firstRow][col]) {394 if("*".equals(headerArray[firstRow][col])) {395 lastCol = col; //定位最后一列,占位符不减1

396 } else{397 lastCol = col-1; //定位最后一列

398 }399 break;400 }401 }402 }403 if(firstRow == lastRow && firstCol ==lastCol) {404 return; //无操作,不执行方法

405 }406 mergedRegion(firstRow + titleRows, lastRow +titleRows, firstCol, lastCol);407 }408 /**合并单元格*/

409 private void mergedRegion(int firstRow, int lastRow, int firstCol, intlastCol) {410 sheet.addMergedRegion(newCellRangeAddress(firstRow, lastRow, firstCol, lastCol));411 }412

413 /**设置行样式*/

414 private void setRowStyle(introwNum, CellStyle style) {415 if(null ==style) {416 return; //样式为空,退出方法

417 }418 Row row =sheet.getRow(rowNum);419 if(row == null) {420 row = sheet.createRow(rowNum); //如果行对象为空,则创建

421 }422 for(int colNum = 0; colNum < colCount; colNum++) {423 Cell cell=row.getCell(colNum);424 if( cell == null){425 cell =row.createCell(colNum);426 cell.setCellValue("");427 }428 cell.setCellStyle(style); //设置样式

429 }430 }431

432 /**初始化样式Map*/

433 private voidinitStyleMap() {434 CellStyle titleStyle =workbook.createCellStyle();435 titleStyle.setAlignment(HorizontalAlignment.CENTER);//水平对齐方式

436 titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直对齐方式437 //style.setFillForegroundColor(HSSFColor.AQUA.index);//前景色438 //style.setFillPattern(FillPatternType.SOLID_FOREGROUND);//模式(前景色)439 //style.setWrapText(true);//自动换行

440 Font font1 = workbook.createFont();//生成一个字体

441 font1.setColor(HSSFColor.RED.index);//字体颜色

442 font1.setFontHeightInPoints((short) 16);//字体大小443 //font.setBold(true);//字体加粗

444 font1.setFontName("Arial");//字体名称

445 titleStyle.setFont(font1);//设置字体

446 styleMap.put("titleStyle", titleStyle); //放入样式Map

447

448 CellStyle headerStyle =workbook.createCellStyle();449 headerStyle.setAlignment(HorizontalAlignment.CENTER);//水平对齐方式

450 headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直对齐方式451 //style.setBorderTop(BorderStyle.THIN);//上边框452 //style.setBorderBottom(BorderStyle.THIN);//下边框453 //style.setBorderLeft(BorderStyle.THIN);//左边框454 //style.setBorderRight(BorderStyle.THIN);//右边框

455 Font font2 = workbook.createFont();//生成一个字体

456 font2.setColor(HSSFColor.BLUE.index);//字体颜色

457 font2.setFontHeightInPoints((short) 10);//字体大小

458 font2.setFontName("Arial");//字体名称

459 headerStyle.setFont(font2);//设置字体

460 styleMap.put("headerStyle", headerStyle); //放入样式Map

461

462 CellStyle contentStyle =workbook.createCellStyle();463 contentStyle.setAlignment(HorizontalAlignment.CENTER);//水平对齐方式

464 contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直对齐方式

465 Font font3 = workbook.createFont();//生成一个字体

466 font3.setFontHeightInPoints((short) 10);//字体大小

467 font3.setFontName("Arial");//字体名称

468 contentStyle.setFont(font3);//设置字体

469 styleMap.put("contentStyle", contentStyle); //放入样式Map

470 }471

472 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值