Apache POI的使用(web网页Excel生成和下载)
程序员文章站
2022-03-15 13:49:30
...
POI简介
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
基本结构
- HSSF - 提供读写[Microsoft Excel](https://baike.baidu.com/item/Microsoft Excel)格式档案的功能。
- XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
- HWPF - 提供读写[Microsoft Word](https://baike.baidu.com/item/Microsoft Word)格式档案的功能。
- HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
- HDGF - 提供读写[Microsoft Visio](https://baike.baidu.com/item/Microsoft Visio)格式档案的功能。
Excel案例基本示例
-
创建Excel文档
public class CreateXL { /** Excel 文件要存放的位置,假定在D盘下*/ public static String outputFile = "D:\\test.xls"; public static void main(String argv[]) { try { // 创建新的Excel 工作簿 HSSFWorkbook workbook = new HSSFWorkbook(); // 在Excel工作簿中建一工作表,其名为缺省值 // 如要新建一名为"效益指标"的工作表,其语句为: // HSSFSheet sheet = workbook.createSheet("效益指标"); HSSFSheet sheet = workbook.createSheet(); // 创建行对象,索引0表示第一行,索引1表示第二行 HSSFRow row = sheet.createRow(0); //在行对象的0索引位置创建单元格对象;一行中的单元格的索引从左到右依次为:0,1,2... HSSFCell cell = row.createCell(0); // 为单元格设置值 cell.setCellValue("增加值"); // 创建字节输出流 FileOutputStream fOut = new FileOutputStream(outputFile); // 把相应的Excel 工作簿数据写入输出流中,输出存盘到电脑硬盘。 workbook.write(fOut); //将流刷出到硬盘 fOut.flush(); // 操作结束,关闭文件 fOut.close(); System.out.println("文件生成..."); } catch (Exception e) { System.out.println("已运行 xlCreate() : " + e); } }
-
读取Excel表
public class ReadXL { //指定要读取的Excel表在硬盘中的位置 public static String fileToBeRead = "D:\\test1.xls"; public static void main(String argv[]) { try { // 读取Excel表,并创建工作簿对象 HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileToBeRead)); //从工作簿中获取指定的工作表对象 HSSFSheet sheet = workbook.getSheet("Sheet1"); // 也可用getSheetAt(int index)按索引引用, // 在Excel文档中,第一张工作表的缺省索引是0, // 其语句为:HSSFSheet sheet = workbook.getSheetAt(0); // 获取行对象 HSSFRow row = sheet.getRow(0); //使用行对象,指定要读取索引处的单元格对象 HSSFCell cell = row.getCell(0); // 输出单元内容,cell.getStringCellValue()就是取所在单元的值 System.out.println("左上端单元是: " + cell.getStringCellValue()); } catch (Exception e) { System.out.println("已运行xlRead() : " + e); } }
案例
将数据库中的数据,生成为Excel表。
-
题目实体类
实体类中的属性就是对应的数据库中表的字段。
/** * 题目实体类 */ public class Question { private String id; private String catalogId; private String catalogName; private String courseId; private String courseName; private String number; private String subject; private String type; private String difficulty; private String analysis; private String analysisVid; private String remark; private String isClassic; private String state; private String reviewStatus; private String createBy; private String createDept; private Date createTime; private String updateBy; private Date updateTime; private String companyId; private String companyName; private String picture; //get set 方法省略... }
-
数据库就不展示了
-
POI——读取数据,封装到Excel表
service业务层
/** * 导出数据到Excel表 */ @Override public ByteArrayOutputStream exportExcel() { //调用数据访问层,查询所有题目数据 List<Question> datas = questionDao.findAll(); //创建工作簿对象 XSSFWorkbook workbook = new XSSFWorkbook(); //创建工作表对象,test.xlsx指定的是工作表的名字 XSSFSheet sheet = workbook.createSheet("test.xlsx"); //设置Excel表头信息 String[] titles = {"ID标识", "所属目录ID", "所属目录名", "所属课程ID", "所属课程名", "题目编号", "subject", "题目类型", "难度", "答案解析", "分析视频", "备注", "是否精选题目", "题目状态", "审核状态", "创建人", "创建部门", "创建时间", "修改人", "修改时间", "公司ID", "公司名", "图片路径"}; //获取行对象 XSSFRow row_0 = sheet.createRow(0); //将数组中的值,设置为Excel的表头 for (int i = 0; i < titles.length; i++) { //获取单元格对象 XSSFCell cell = row_0.createCell(i); //设置单元格内容 cell.setCellValue(titles[i]); } // 设置内容 //使用反射,获取question题目实体类的字段属性(0-22) Field[] fields = Question.class.getDeclaredFields(); //遍历list集合 for (int j = 0; j < datas.size(); j++) { //获取对象 Question question = datas.get(j); //获取写入数据的行对象 XSSFRow row_temp = sheet.createRow(j + 1); //循环将对象的数据写入单元格 for (int i = 0; i <= 22; i++) { //使用行对象创建单元格对象,参数为行对象中的第几个单元格,从0开始 XSSFCell cell = row_temp.createCell(i); //字段为private修饰,需要暴力** fields[i].setAccessible(true); //获取指定对象的指定字段的值 Object o = null; try { o = fields[i].get(question); } catch (IllegalAccessException e) { e.printStackTrace(); } //判断o是否为空,不为空则调用toString方法,然后为单元格赋值 if (o != null) { String value = o.toString(); //为单元格赋值 cell.setCellValue(value); } } } //将内存中的数据写入到字节数组输出流中,返回给servlet; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { workbook.write(byteArrayOutputStream); //关闭流 workbook.close(); } catch (IOException e) { e.printStackTrace(); } return byteArrayOutputStream; }
web层
/** * 导出数据库数据到Excel表 */ private void toExport(HttpServletRequest request, HttpServletResponse response) throws IOException { //设置响应的数据类型为XLSX格式 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); //因为游览器不能直接使用中文,需要进行编码 String filename = new String("题目数据.xlsx".getBytes(), "iso8859-1"); //添加Content-disposition响应头,在用户请求下载文件的时候,设置文件的文件名 response.addHeader("content-disposition", "attachment;filename=" + filename); //获取响应的流对象 ServletOutputStream os = response.getOutputStream(); //调用业务层 ByteArrayOutputStream outputStream = questionService.exportExcel(); //将原始数据流对象中的数据写入响应流中 outputStream.writeTo(os); //将响应输出流中的数据刷新到游览器 os.flush(); //关流 outputStream.close(); }
实现思想说明
将数据库的某表的数据全部读取出来,每一行数据封装成一个实体类,将全部实体类用集合封装;然后使用反射,获取实体类的字段,并获取每个实体类的每个字段的值,写入到响应的单元格对象(前提是要创建好工作簿、工作表等)
获取指定对象的指定字段的值-> field字段.get(实例对象);
注意:一般来说实体类的字段都是私有化的private
修饰,所以在获取字段的值之前,需要用反射暴力**->fields字段.setAccessible(true);
。
下一篇: 爆囧,家里呆着精神很压力大呀!