最近在做一个文史类统计项目,许多地方需要用到导出excel报表。之前用的是公司的poi导出,最后听群友说csv的导出会比poi快很多。但是csv文件是以“,”分割文件的。如果数据中逗号比较多就会导致数据混乱。

①POI导出

1.导入poi依赖或者导入jar包E:\百度\poi-3.9.jar

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version><scope>compile</scope>
</dependency>

2.excel帮助类

package com.yszh.pdf.listdemo; import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;public class ExcelUtil {/*** 导出excel,带合并单元格表头* @param title sheet名称及excel标题名称* @param rowsName   每列列头名称数组* @param dataList  数据内容* @param fileName 文件名* @param response 输出流* @throws Exception*/public void exportExcel(String title,String[] rowsName,List<Object[]> dataList,String fileName,HttpServletResponse response) throws Exception{OutputStream output = response.getOutputStream();response.reset();response.setHeader("Content-disposition","attachment; filename=" + fileName + ".xls");response.setContentType("application/msexcel");this.export(title,rowsName,dataList,true,output);this.close(output);}/*** 导出excel,不带合并单元格表头* @param title sheet名称及excel标题名称* @param rowsName   每列列头名称数组* @param dataList  数据内容* @param fileName 文件名* @param response 输出流* @throws Exception*/public void exportExcelNoTitle(String title,String[] rowsName,List<Object[]> dataList,String fileName,HttpServletResponse response) throws Exception{OutputStream output = response.getOutputStream();response.reset();response.setHeader("Content-disposition","attachment; filename=" + fileName + ".xls");response.setContentType("application/msexcel");this.export(title,rowsName,dataList,false,output);this.close(output);}/*** 导出excel* @param title sheet名称及excel标题名称* @param rowName   每列列头名称数组* @param dataList  数据内容* @param tag 是否带表头* @param out 输出流* @throws Exception*/private void export(String title,String[] rowName,List<Object[]> dataList,boolean tag,OutputStream out) throws Exception {try {// 创建工作簿对象HSSFWorkbook workbook = new HSSFWorkbook();// 创建工作表HSSFSheet sheet = workbook.createSheet(title);// 产生表格标题行HSSFRow rowm = sheet.createRow(0);//创建表格标题列HSSFCell cellTiltle = rowm.createCell(0);// sheet样式定义;    getColumnTopStyle();    getStyle()均为自定义方法 --在下面,可扩展// 获取列头样式对象HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);// 获取单元格样式对象HSSFCellStyle style = this.getStyle(workbook);//设置居中style.setAlignment(HSSFCellStyle.ALIGN_CENTER);int titleNum = 0;if(tag){//合并表格标题行,合并列数为列名的长度,第一个0为起始行号,第二个1为终止行号,第三个0为起始列好,第四个参数为终止列号sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (rowName.length - 1)));//设置标题行样式cellTiltle.setCellStyle(columnTopStyle);//设置标题行值cellTiltle.setCellValue(title);titleNum=2;}// 定义所需列数int columnNum = rowName.length;// 在索引2的位置创建行(最顶端的行开始的第二行)HSSFRow rowRowName = sheet.createRow(titleNum);// 将列头设置到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(columnTopStyle);}// 将查询出的数据设置到sheet对应的单元格中for (int i = 0; i < dataList.size(); i++) {// 遍历每个对象Object[] obj = dataList.get(i);// 创建所需的行数HSSFRow row = sheet.createRow(i + titleNum+1);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 = currentCell.getStringCellValue().getBytes().length;if (columnWidth < length) {columnWidth = length;}}}}if (colNum == 0) {sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);} else {sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);}}workbook.write(out);} catch (Exception e) {e.printStackTrace();}}/*** 列头单元格样式* @param workbook* @return*/private HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {// 设置字体HSSFFont font = workbook.createFont();// 设置字体大小font.setFontHeightInPoints((short) 11);// 字体加粗font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 设置字体名字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;}/*** 列数据信息单元格样式* @param workbook* @return*/private HSSFCellStyle getStyle(HSSFWorkbook workbook) {// 设置字体HSSFFont font = workbook.createFont();// 设置字体大小// font.setFontHeightInPoints((short)10);// 字体加粗// font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 设置字体名字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;}/*** 关闭输出流* @param os*/private void close(OutputStream os) {if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}}
}

3.使用poi导出的时候只需要调用exportExce(String title,String[] rowsName,List<Object[]> dataList,String fileName,HttpServletResponse response)方法就可以了。title定义表名字,rowsName:定义excel表格的表头

@GetMapping("exportExcelFontDisplayAboutReports")@ApiOperation(value = "前台展示报告列表导出",notes="isAll:0单选导出,isAll:1表示待筛选条件的导出")public void exportExcelFontDisplayAboutReports(HttpServletResponse response,String[] entityId,Integer isAll,Integer[] ids, String[] level, String[] structId, String[] year, String[] province, String keyWord){String title = "村庄调查报告列表";String[] rowsName = new String[]{"序号","名称","字数","页数","类型","年份","评级"};//定义一个Object[]类型的数组,数组中每个位置对应的元素依次是表头对应的数据List<Object[]> dataLists = new ArrayList<>();//从数据库中查出数据封装到Map中List<Map<String,Object>> export = null;Integer num = 0;if(isAll == 0){export = iOralHisFilesService.getVillageFileByConditionToExcel(entityId,null,null,null,null,null,null);}else{export = iOralHisFilesService.getVillageFileByConditionToExcel(null,ids,level,structId,year,province,keyWord);}//遍历Map集合并赋值给dataLists中的数组元素for (Map<String,Object> map: export) {Object[] objects = new Object[rowsName.length];objects[0] = num++;objects[1] = map.get("FileName") != null ? map.get("FileName") : " ";objects[2] = map.get("WordCount") != null ? map.get("WordCount") : " ";objects[3] = map.get("FileSize") != null ? map.get("FileSize") : " ";objects[4] = map.get("structName") != null ? map.get("structName") : " ";objects[5] = map.get("year") != null ? map.get("year") : " ";objects[6] = map.get("level") != null ? map.get("level") : " ";dataLists.add(objects);}ExcelUtil excelUtil = new ExcelUtil();try {//生成Excel文件的文件名String fileName = new String("村庄调查报告列表".getBytes("UTF-8"), "iso-8859-1");excelUtil.exportExcel(title,rowsName,dataLists,fileName,response);} catch (Exception e) {e.printStackTrace();}}

注意:在给表头赋值的时候一定要做判断,判断查出来的数据是否为空,(为空的话就需要将他设置为“ ”)不然会报错

②csv的导出

在做csv的导出的时候,由于从网上看的发给发不具有通用性,就将她封装了一下。其中利用到了反射的相关知识。只需要传几个简单的参就可以导出报表了

1.导入csv依赖:

<dependency><groupId>net.sourceforge.javacsv</groupId><artifactId>javacsv</artifactId><version>2.0</version>
</dependency>

2.封装的csv导出方法

/**** @param dataList 封装成Pojo类的List* @param tableName 表头名字* @param request request* @param response response* @param fileName 文件名* @param methodNames 需要导入字段的get方法名字(如果需要添加序号,请在数组前添加一个"num",没有序号就传get方法名字)* @param <T>* @throws Exception*/public static<T> void exportByCVS(List<T> dataList, String[] tableName, HttpServletRequest request, HttpServletResponse response, String fileName, String[] methodNames) throws Exception {List<T> t = dataList;// 文件名request.getHeader("User-Agent");response.setCharacterEncoding(request.getCharacterEncoding());response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment; filename=" + fileName);ServletOutputStream out = response.getOutputStream();CsvWriter write = new CsvWriter(out, ',', Charset.forName("gb2312"));write.setForceQualifier(true);Integer num = 0;//定义表头write.writeRecord(tableName);//比如说查出来10条数据,首先遍历这10条数据,利用反射根据表头需要的信息循环每条数据中的get方法进行赋值//每条信息对应的数据内容中get方法中的返回值将会存入数组之中。每次循环完之后调用 write.writeRecord(insert)方法姐可以将//数据插入到文件中for (int i = 0; i < t.size(); i++) {//定义表头数据的长度String[] insert = new String[tableName.length];//从数据库中查出来的字段根据需要获取字段对应的get方法for (int k = 0; k < methodNames.length; k++) {//获取数据源中泛型的类型T t1 = t.get(i);//如果在methodNames中定义了num就表示需要序号这一列if( k == 0 && "num".equals(methodNames[0])){insert[0] = String.valueOf(++num);}else{//获取数据源List中泛型的类名String name = t1.getClass().getName();//根据类名加载字节码文件Class<?> aClass =  Class.forName(name);//根据传入的参数获取数据源List中泛型中的get方法Method paramGetMethod = aClass.getMethod(methodNames[k]);//获取数据源List中泛型中的get方法的返回值并判断类型Type returnType = paramGetMethod.getAnnotatedReturnType().getType();String temp = null;//判断get方法返回值的类型,防止类型转换错误。此处调用数据源中泛型中的对象引用区执行方法就可以获得数据if("java.lang.Integer".equals(returnType.getTypeName())){temp = String.valueOf((Integer) paramGetMethod.invoke(t1));}else{temp = (String)paramGetMethod.invoke(t1);}//写入数据中insert[k] = temp != null ? temp : "";}}try {//调用依赖中csv的方法去将数据中的数据写入文件中write.writeRecord(insert);} catch (IOException e) {e.printStackTrace();}}write.flush();write.close();response.flushBuffer();}

3.调用导出方法。传入对应的参数即可

  @ResourceOralHisFilesMapper oralHisFilesMapper;@GetMapping("exportExcelFontDisplayAboutReportsToCSV")@ApiOperation(value = "前台展示报告列表导出",notes="isAll:0单选导出,isAll:1表示待筛选条件的导出")public void exportExcelFontDisplayAboutReportsToCSV(HttpServletRequest request,HttpServletResponse response,String[] entityId,Integer isAll,Integer[] ids, String[] level, String[] structId, String[] year, String[] province, String keyWord) throws Exception {String[] tableName = { "名称","字数","页数","类型","年份","评级"};String fileName = new String("民国调查报告列表.csv".getBytes("UTF-8"), "ISO-8859-1");String[] methodNames = {"getFileName","getWordCount","getFileSize","getTypeName","getYear","getLevel"};List<OralHisFiles> dataLists = null;Integer num = 0;if(isAll == 0){dataLists = oralHisFilesMapper.getVillageFileByCondition(null,ids,level,structId,year,province,keyWord);}else{dataLists = oralHisFilesMapper.getVillageFileByConditionTocsv(ids,level,structId,year,province,keyWord);}CsvUtils.exportByCVS(dataLists,tableName,request,response,fileName,methodNames);}

备注:csv文件是以“,”分割文件的。如果你的导入数据中又大量的逗号,建议使用poi的形式导出。但相比较而言,他的导出速度会非常快。

Java导出excel中poi的导出和csv导出excel相关推荐

  1. oracle 数据 导出 excel 自动分多个文件,从oracle数据库中导出大量数据到excel中为什么自动分成了好几个excel文件《excel表格新手入门》...

    EXCEL中一个单元格中多行文本如何导入或复制到SQL SERVER 数据库表中? 保留换行符保存进数据表啊,读取出来显示的时候根据需要进行转换就行了,比如要在网页上显示,可以把换行符转换成HTML的 ...

  2. 如何排两列的序计算机考试,excel中两列数据怎么一起排序?excel两列同时排序的方法...

    excel中两列数据怎么一起排序?excel两列同时排序的方法 腾讯视频/爱奇艺/优酷/外卖 充值4折起 我们在使用Excel对数列排序时,有时会碰到需要对两列数据同时排序,下面就跟大家详细介绍操作方 ...

  3. 计算机表格嵌套,Excel中轻松玩转“动态”表格嵌套EXCEL基本教程 -电脑资料

    使用Excel做表格,真是好处多多,也可以说是"地球人都知道",但是如何有效提高办公效率,做出即美观效率又高的表格就不是每个人都知道的了, 应用场合:某表格中有一部分内容是需要经常 ...

  4. java 复杂报表_Java+POI+模板”一:打造复杂Excel 报表

    1 设计思路 Java 对于Excel 的操作一般借助于POI 类库,由于有些报表的表头比较复杂,直接用POI 控制报表的生成比较困难,这时可以先制作Excel 报表模板,而后再通过Java 调用PO ...

  5. EXCEL中IF函数多重嵌套使用和EXCEL下拉框

    =IF(A1>=60,"及格","不及格") 这是一般通过公式里面IF函数所能做到的,但是EXCEL中没有java中case这样多条件的判断语句,因此需要 ...

  6. python在excel中的应用-Python利用pandas处理Excel数据的应用详解

    最近迷上了高效处理数据的pandas,其实这个是用来做数据分析的,如果你是做大数据分析和测试的,那么这个是非常的有用的!!但是其实我们平时在做自动化测试的时候,如果涉及到数据的读取和存储,那么而利用p ...

  7. php读取excel中数据库,ThinkPHP 框架实现的读取excel导入数据库操作示例

    本文实例讲述了ThinkPHP 框架实现的读取excel导入数据库操作.分享给大家供大家参考,具体如下: 入口文件中: require_once VENDOR_PATH.'PHPExcel/PHPEx ...

  8. excel中python是什么意思_python在excel中的应用是什么

    python在excel中的应用:1.pandas操作Excel指定的单行:2.读取指定的多行:3.读取指定的行列:4.读取指定的多行多列值:5.获取所有行的指定列:6.获取行号并打印输出. 本教程操 ...

  9. 怎么用计算机打分数,电脑excel中分数怎么打出来(图解excel分数输入法)

    在日常工作中,我们经常需要在excel中输入分数,默认情况下,当我们直接输入分数,比如输入"9/16" 回车后,会发现系统显示的却是日期数据,如下图所示,那么分数该怎么输入呢?今天 ...

最新文章

  1. leetcode 567. Permutation in String 字符串的排列 滑动窗口法
  2. python创建float型的列表_如何在Python中进行列表的创建?
  3. CyclicBarrier及CountDownLatch的使用
  4. 怎么让电脑屏幕一直亮着_电视机指示灯亮不开机怎么办 电视机故障及维修介绍【详解】...
  5. 软件工程中交流的思考
  6. WPF窗体最小化到任务栏
  7. 揭秘!业界创新的代码仓库加密技术
  8. 惠普:存储为未来而设计
  9. 【LeetCode】124. Binary Tree Maximum Path Sum
  10. POJ 3348 Cows
  11. 兄弟打印机内存已满清零方法_兄弟打印机全部清零操作方法
  12. excel如何隔行填充颜色
  13. oeasy教您玩转python - 003 - # - 继续运行
  14. 人工智能没成果,年底的PPT怎么写?腾讯科学家张潼离职的后续讨论
  15. A - 卡牌游戏 III
  16. 常见的继电接触器控制线路总结
  17. linux-top命令备忘
  18. 微信和淘宝最赤裸的分析
  19. Ubuntu20.04系统如何安装google chrome浏览器
  20. 《笑傲江湖》一共有几个版本? -- 影评

热门文章

  1. 关注Game内嵌Flash UI
  2. 苹果cmsv10迅雷下载站模板高权重好看的影视源码
  3. PHP 集成银联支付
  4. 02 双冒号作用域运算符
  5. 投资开零食店谨防零食多这个骗子
  6. 企业微信自建应用审批流程踩坑全过程(uni-app)
  7. word中页面上下出现横线无法删除
  8. 最新计算机专业毕业设计论文选题源码演示录像下载(开题报告任务书PPT毕业答辩模板(jsp/java选题 第1页)
  9. 专访孙睿 :能做自己,去做自己想做的,是件挺幸福的事儿
  10. Mac上Pycharm激活