java 操作excel 的 POI技术

这篇博客介绍了如何使用Java的POI库进行Excel的导入和导出操作。重点在于将数据库数据转换为Excel文件并传送给客户端,过程中涉及了文件传输格式设置、输出流创建、浏览器类型判断及文件名编码防止乱码问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.POI导入

1.首先从页面获取文件

  1. //定义一个File属性接收导入的xsl文件
  2. private File regionFile;
  3. public void setRegionFile(File regionFile) {
  4. this.regionFile = regionFile;
  5. }

 2.使用POI读取xsl文件,并创建workbook

  1. public String importXsl() throws FileNotFoundException, IOException {
  2. //使用POI读取xsl文件
  3. HSSFWorkbook hssfWorkbook = new HSSFWorkbook(new FileInputStream(regionFile));
  4. //当前标签页
  5. HSSFSheet sheetAt = hssfWorkbook.getSheetAt(0);
  6. List<Region> regionList = new ArrayList();
  7. //遍历得到row每行
  8. for (Row row : sheetAt) {
  9. //判断第一行并去掉它
  10. int rowNum = row.getRowNum();
  11. if(rowNum == 0) {
  12. continue;
  13. }
  14. String id = row.getCell(0).getStringCellValue();
  15. String province = row.getCell(1).getStringCellValue();
  16. String city = row.getCell(2).getStringCellValue();
  17. String district = row.getCell(3).getStringCellValue();
  18. String postcode = row.getCell(4).getStringCellValue();
  19. //将省份,城市,区域字符串合并
  20. String shortcode = province.substring(0, province.length() - 1) + city.substring(0, city.length() - 1) + district.substring(0, district.length() - 1);
  21. //使用pingyin4j 将汉字转为拼音
  22. String[] headByString = PinYin4jUtils.getHeadByString(shortcode);
  23. shortcode = StringUtils.join(headByString);
  24. String citycode = PinYin4jUtils.hanziToPinyin(city,"");
  25. //将参数封装到Region对象
  26. Region region = new Region(id, province, city, district, postcode, shortcode, citycode, null);
  27. regionList.add(region);
  28. }
  29. //将list集合给service进行保存(使用list存储,只开启一个事务,效率提升)
  30. regionService.importXsl(regionList);
  31. return NONE;
  32. }

2.POI导出xls文件

 1.先查询数据库得到需要的数据(我这里是用list<Subarea>存的结果集)

  1. //得到所有的分区数据
  2. List<Subarea> findAll = suberareaService.findAll();
2.在内存中先创建一个excuel文件
  1. //先在内存中创建一个excel文件
  2. HSSFWorkbook workbook = new HSSFWorkbook();
3.与导入xls相反,创建sheet标签页和row行
  1. //创建标签页
  2. HSSFSheet sheet = workbook.createSheet("分区数据");
4.先创建首行的信息
  1. //创建首行row信息
  2. HSSFRow firstRow = sheet.createRow(0);
  3. firstRow.createCell(0).setCellValue("分区编号");
  4. firstRow.createCell(1).setCellValue("开始编号");
  5. firstRow.createCell(2).setCellValue("结束编号");
  6. firstRow.createCell(3).setCellValue("位置信息");
  7. firstRow.createCell(4).setCellValue("省市区");

5.遍历数据库查询的结果,将结果存到Excel文件中
  1. //将数据库中数据放入
  2. for (Subarea subarea : findAll) {
  3. HSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);
  4. row.createCell(0).setCellValue(subarea.getSubareaid());;
  5. row.createCell(1).setCellValue(subarea.getStartnum());;
  6. row.createCell(2).setCellValue(subarea.getEndnum());;
  7. row.createCell(3).setCellValue(subarea.getPosition());;
  8. row.createCell(4).setCellValue(subarea.getRegion().getName());;
  9. }

6.将已经封装好的文件传给客户端(重点)(一个流,两个头)

 6.1首先通过文件的名称后缀,查询得到设置传输格式的ContextType

  1. //第三步:使用输出流进行文件下载(一个流、两个头)
  2. String filename = "分区数据.xls";
  3. //得到文件类型
  4. String contentType = ServletActionContext.getServletContext().getMimeType(filename);

 6.2设置传输类型,创建输出流

  1. ServletOutputStream out = ServletActionContext.getResponse().getOutputStream();
  2. //储存文件类型格式 like(text/html;charset=utf-8)
  3. ServletActionContext.getResponse().setContentType(contentType);

6.3得到客户端的类型,根据类型将文件名称编码(主要是汉字会造成乱码,不同的浏览器编码格式不同)

  1. //得到客户端的类型,根据类型将文件名称继续编码
  2. String agent = ServletActionContext.getRequest().getHeader("User-Agent");
  3. //使用工具类 根据User-Agent(浏览器类型)来编码文件名
  4. filename = FileUtils.encodeDownloadFilename(filename, agent);
  5. //将得到的文件名称放入到响应头中
  6. ServletActionContext.getResponse().setHeader("content-disposition", "attachment;filename="+filename);

 6.4直接使用POI输出即可

  1. //使用POI方法写回文件
  2. workbook.write(out);


POI数据库数据转Excel并输出全部代码

  1. public String exportXls() throws IOException {
  2. //得到所有的分区数据
  3. List<Subarea> findAll = suberareaService.findAll();
  4. //使用POI技术将数据转为xsl文件
  5. //先在内存中创建一个excel文件
  6. HSSFWorkbook workbook = new HSSFWorkbook();
  7. //创建标签页
  8. HSSFSheet sheet = workbook.createSheet("分区数据");
  9. //创建首行row信息
  10. HSSFRow firstRow = sheet.createRow(0);
  11. firstRow.createCell(0).setCellValue("分区编号");
  12. firstRow.createCell(1).setCellValue("开始编号");
  13. firstRow.createCell(2).setCellValue("结束编号");
  14. firstRow.createCell(3).setCellValue("位置信息");
  15. firstRow.createCell(4).setCellValue("省市区");
  16. //将数据库中数据放入
  17. for (Subarea subarea : findAll) {
  18. HSSFRow row = sheet.createRow(sheet.getLastRowNum() + 1);
  19. row.createCell(0).setCellValue(subarea.getSubareaid());;
  20. row.createCell(1).setCellValue(subarea.getStartnum());;
  21. row.createCell(2).setCellValue(subarea.getEndnum());;
  22. row.createCell(3).setCellValue(subarea.getPosition());;
  23. row.createCell(4).setCellValue(subarea.getRegion().getName());;
  24. }
  25. //第三步:使用输出流进行文件下载(一个流、两个头)
  26. String filename = "分区数据.xls";
  27. //得到文件类型
  28. String contentType = ServletActionContext.getServletContext().getMimeType(filename);
  29. ServletOutputStream out = ServletActionContext.getResponse().getOutputStream();
  30. //储存文件类型格式 like(text/html;charset=utf-8)
  31. ServletActionContext.getResponse().setContentType(contentType);
  32. //得到客户端的类型,根据类型将文件名称继续编码
  33. String agent = ServletActionContext.getRequest().getHeader("User-Agent");
  34. //使用工具类 根据User-Agent(浏览器类型)来编码文件名
  35. filename = FileUtils.encodeDownloadFilename(filename, agent);
  36. //将得到的文件名称放入到响应头中
  37. ServletActionContext.getResponse().setHeader("content-disposition", "attachment;filename="+filename);
  38. //使用POI方法写回文件
  39. workbook.write(out);
  40. return NONE;
  41. }

通过请求头的User-Agent 判断浏览器类型并将文件名称编码的工具类

  1. package com.itheima.bos.utils;
  2. import java.io.IOException;
  3. import java.net.URLEncoder;
  4. import sun.misc.BASE64Encoder;
  5. public class FileUtils {
  6. /**
  7. * 下载文件时,针对不同浏览器,进行附件名的编码
  8. *
  9. * @param filename
  10. * 下载文件名
  11. * @param agent
  12. * 客户端浏览器
  13. * @return 编码后的下载附件名
  14. * @throws IOException
  15. */
  16. public static String encodeDownloadFilename(String filename, String agent)
  17. throws IOException {
  18. if (agent.contains("Firefox")) { // 火狐浏览器
  19. filename = "=?UTF-8?B?"
  20. + new BASE64Encoder().encode(filename.getBytes("utf-8"))
  21. + "?=";
  22. filename = filename.replaceAll("\r\n", "");
  23. } else { // IE及其他浏览器
  24. filename = URLEncoder.encode(filename, "utf-8");
  25. filename = filename.replace("+"," ");
  26. }
  27. return filename;
  28. }
  29. }














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值