Java教程:使用POI读取excel文档(根据BV1bJ411G7Aw整理)

最近公司需要我做一个导出Excel表格的功能,为此来学习一下POI,在这里记录一下学习笔记。B站直接搜BV1bJ411G7Aw就能找到视频。

一、简介

poi如何操作表格

二、入门案例

2.1 从Excel文件读取数据
2.1.1 步骤文字描述

1.创建工作簿
2.获取工作表
3.遍历工作表获得行对象
4.遍历行对象获取单元格对象
5.获得单元格中的值

2.2.2 代码
先在pom中导入依赖

<!--poi--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.14</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.14</version></dependency>

在桌面(你喜欢的地方)创建一个xlsx,输入一些简单数据


按照步骤书写代码

// 1.获取工作簿XSSFWorkbook workbook = new XSSFWorkbook("C:\\Users\\ghost\\Desktop\\hello.xlsx");// 2.获取工作表// xlsx第一个工作簿(Sheet1),下标从0开始,0就是第一个XSSFSheet sheet = workbook.getSheetAt(0);/*使用加强for循环的方式*/// 3.获取行for (Row row : sheet) {// 4.获取单元格for (Cell cell: row) {// 获取单元格中的内容String value = cell.getStringCellValue();System.out.println(value);}}// 释放资源workbook.close();

运行代码
我们会发现能够正常读到,但是因为我们也打开着这个文档,所以显示被占用

关掉再运行就一切正常了

我们再试试不使用加强for循环的方式

// 1.获取工作簿XSSFWorkbook workbook = new XSSFWorkbook("C:\\Users\\ghost\\Desktop\\hello.xlsx");// 2.获取工作表// xlsx第一个工作簿(Sheet1),下标从0开始,0就是第一个XSSFSheet sheet = workbook.getSheetAt(0);/*使用普通循环的方式*/// 开始索引(0) 结束索引int lastRowNum = sheet.getLastRowNum(); //行的结束索引for (int i = 0; i <= lastRowNum; i++) {// 拿到行XSSFRow row = sheet.getRow(i);if (row != null){short cellNum = row.getLastCellNum(); //单元格的结束索引for (int j = 0; j <= cellNum; j ++){XSSFCell cell = row.getCell(j);// 单元格不为空就去拿他的值if (cell != null){String stringCellValue = cell.getStringCellValue();System.out.println(stringCellValue);}}}}// 释放资源workbook.close();

能够正常运行

2.2 向Excel文件写入数据
2.2.1 步骤文字描述

1.创建一个Excel文件
2.创建工作表
3.创建行
4.创建单元格赋值
5.通过输出流将对象下载到磁盘

2.2.2 代码

// 1.创建工作簿XSSFWorkbook workbook = new XSSFWorkbook();// 2.创建工作表XSSFSheet sheet = workbook.createSheet("工作表一");// 3.创建行XSSFRow row1 = sheet.createRow(0); //第一行// 创建单元格row1.createCell(0).setCellValue("众"); //第一行第一格row1.createCell(1).setCellValue("子"); //第一行第二格row1.createCell(2).setCellValue("之"); //第一行第三格row1.createCell(3).setCellValue("爹"); //第一行第四格XSSFRow row2 = sheet.createRow(1); //第二行// 创建单元格row2.createCell(0).setCellValue("众"); //第二行第一格row2.createCell(1).setCellValue("子"); //第二行第二格row2.createCell(2).setCellValue("之"); //第二行第三格row2.createCell(3).setCellValue("爹"); //第二行第四格// 输出流FileOutputStream out = new FileOutputStream("C:\\Users\\ghost\\Desktop\\hello1.xlsx");// 写入workbook.write(out);// 刷新流out.flush();// 释放资源out.close();workbook.close();// 给个成功提示System.out.println("写入成功!");

运行代码

回到桌面查看可以看到多出来一个hello1

三、配合数据库使用

3.1 读取Excel文件数据
首先在随便一个地方(我这里在桌面)创建一个product.xlsx

然后写入一些数据

创建数据库

创建实体类(getset方法、有参无参构造、toString)

这里使用控制台来代替前端页面,主要是展示功能代码

public class PioShow {public static void main(String[] args) throws IOException {// 通过键盘录入ScannerScanner scanner = new Scanner(System.in);System.out.println("请输入你要选择的功能:1、导入;2、导出");int num = scanner.nextInt();if (num == 1){// 1.导入// 1.1读取excel表中的数据System.out.println("请输入您要读取的文件位置(不包含空格):");String path = scanner.next();List<Pio> pioList = read(path);System.out.println(pioList);// 1.2将数据接入到数据库中}else if (num == 2){// 2.导出// 2.1读取数据库中的数据// 2.2将数据写入到excel表格中}else {System.out.println("输入有误,请重新启动!");}}public static List<Pio> read(String path) throws IOException {// 用来存储下面的存储单元格的listList<Pio> pioList = new ArrayList<>();// 1.获取工作簿XSSFWorkbook xssfWorkbook = new XSSFWorkbook(path);// 2.获取工作表XSSFSheet sheet = xssfWorkbook.getSheetAt(0); //0代表第一个工作表int lastRowNum = sheet.getLastRowNum();// i=1,第一行的商品编号、商品名称、商品价格(单位:元/斤)、商品库存(单位:吨)不拿,不然报错java.lang.NumberFormatException: For input string: "商品编号"for (int i = 1; i <= lastRowNum; i++) {// 拿到行XSSFRow row = sheet.getRow(i);if (row != null){// 用户存储每次获取的单元格内容List<String> list = new ArrayList<>();// 拿到单元格for (Cell cell : row){if (cell != null){// 手动设置为字符串类型,避免乱码cell.setCellType(Cell.CELL_TYPE_STRING);// 获取单元格中的内容String value = cell.getStringCellValue();// 防止某些单元格为空if (value != null && !"".equals(value)){// 获取到的单元格内容放到list里面list.add(value);}}}if (list.size() > 0){// 0-3对应:主键,商品名称,商品价格,商品库存。除了商品名称本身就是String类型,其他全部要转换为对应类型Pio pio = new Pio(Integer.parseInt(list.get(0)), list.get(1), Double.parseDouble(list.get(2)), Integer.parseInt(list.get(3)));// 封装到List里pioList.add(pio);}}}return pioList;}
}

启动,然后输入文件路径,可以看到能够读取到里面的数据

最后添加保存到数据库的代码(具体见视频)

3.2 写出到Excel文件
这里以springBoot为例(之前自己写的一个小说网站),需要jdbc的例子的到视频看

注释掉的部分是固定写到桌面;这里用的是jsp,等待jsp返回地址,不为空就执行导出到excel

// 从数据库读取数据写到Excel中@RequestMapping("/writePio")public String writePio(String path) throws IOException {//FileSystemView fsv = FileSystemView.getFileSystemView();  //注意了,这里重要的一句//System.out.println(fsv.getHomeDirectory());               //得到桌面路径//path = fsv.getHomeDirectory() + "\\aaa.xlsx";// 2.导出// 2.1读取数据库中的数据List<Pio> pioList = novelService.selectPioAll();// 2.2将数据写入到excel表格中if(path != null) {write(pioList, path);System.out.println("写入成功!");}return "writePio";}

novelService.selectPioAll()的内容,就是简单的查询表里全部字段



write方法,正常需要封装到util里,这里就随便放了

百分比可以做通过率或者什么比例的数据展示

public void write(List<Pio> pioList, String path) throws IOException {// 1.创建一个工作簿XSSFWorkbook xssfWorkbook = new XSSFWorkbook();// 2.创建工作表XSSFSheet sheet = xssfWorkbook.createSheet("商品");// 3.创建行XSSFRow row = sheet.createRow(0);row.createCell(0).setCellValue("商品编号");row.createCell(1).setCellValue("商品名称");row.createCell(2).setCellValue("商品价格(单位:元/斤)");row.createCell(3).setCellValue("商品库存(单位:吨)");DecimalFormat df = new DecimalFormat("0.0");//设置保留位数,下面除法的百分比用到。直接用"/"是保留整数的除,"%"是取余,都不适用for (int i = 0; i < pioList.size(); i++) {XSSFRow row1 = sheet.createRow(i + 1);row1.createCell(0).setCellValue(pioList.get(i).getPid());row1.createCell(1).setCellValue(pioList.get(i).getPname());row1.createCell(2).setCellValue(pioList.get(i).getPrice() + "/" + pioList.get(i).getPrice() + "(" + df.format((float)pioList.get(i).getPrice()/pioList.get(i).getPrice()*100) + "%" + ")");row1.createCell(3).setCellValue(pioList.get(i).getPstock());}FileOutputStream fileOutputStream = new FileOutputStream(path);xssfWorkbook.write(fileOutputStream);fileOutputStream.flush();fileOutputStream.close();xssfWorkbook.close();}

jsp里的内容

数据库的内容

在主界面随便找个地方作为入口

到主界面点进去

输入地址,这里输入在桌面创建一个product.xlsx


回到桌面查看


3.3 展示数据和一键导出为Excel表格
controller层

// 从数据库读取数据写到Excel中@RequestMapping("/writePio")public String writePio(String path, HttpServletResponse servletResponse, Model model) throws IOException {/*FileSystemView fsv = FileSystemView.getFileSystemView();  //注意了,这里重要的一句System.out.println(fsv.getHomeDirectory());               //得到桌面路径path = fsv.getHomeDirectory() + "\\aaa.xlsx";*/// 2.导出// 2.1读取数据库中的数据List<Pio> pioList = novelService.selectPioAll();model.addAttribute("pioList", pioList);// 2.2将数据写入到excel表格中if(path != null) {write(pioList, path);download(path, servletResponse);System.out.println("写入成功!");}return "writePio";}

调用Uitl里的两个方法:write,download
write方法

public void write(List<Pio> pioList, String path) throws IOException {// 1.创建一个工作簿XSSFWorkbook xssfWorkbook = new XSSFWorkbook();// 2.创建工作表XSSFSheet sheet = xssfWorkbook.createSheet("商品");// 3.创建行XSSFRow row = sheet.createRow(0);row.createCell(0).setCellValue("商品编号");row.createCell(1).setCellValue("商品名称");row.createCell(2).setCellValue("商品价格(单位:元/斤)");row.createCell(3).setCellValue("商品库存(单位:吨)");DecimalFormat df = new DecimalFormat("0.0");//设置保留位数,下面除法的百分比用到。直接用"/"是保留整数的除,"%"是取余,都不适用for (int i = 0; i < pioList.size(); i++) {XSSFRow row1 = sheet.createRow(i + 1);row1.createCell(0).setCellValue(pioList.get(i).getPid());row1.createCell(1).setCellValue(pioList.get(i).getPname());row1.createCell(2).setCellValue(pioList.get(i).getPrice() + "/" + pioList.get(i).getPrice() + "(" + df.format((float)pioList.get(i).getPrice()/pioList.get(i).getPrice()*100) + "%" + ")");row1.createCell(3).setCellValue(pioList.get(i).getPstock());}FileOutputStream fileOutputStream = new FileOutputStream(path);xssfWorkbook.write(fileOutputStream);fileOutputStream.flush();fileOutputStream.close();xssfWorkbook.close();}

download方法

 /*** @param path     想要下载的文件的路径* @param response* @功能描述 下载文件: 将文件以流的形式一次性读取到内存,通过响应输出流输出到前端*/@RequestMapping("/download")public void download(String path, HttpServletResponse response) {try {// path是指想要下载的文件的路径File file = new File(path);System.out.println(file.getPath());// 获取文件名String filename = file.getName();// 获取文件后缀名String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();System.out.println(("文件后缀名:" + ext));// 将文件写入输入流FileInputStream fileInputStream = new FileInputStream(file);InputStream fis = new BufferedInputStream(fileInputStream);byte[] buffer = new byte[fis.available()];fis.read(buffer);fis.close();// 清空responseresponse.reset();// 设置response的Headerresponse.setCharacterEncoding("UTF-8");// Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存// attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"// filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));// 告知浏览器文件的大小response.addHeader("Content-Length", "" + file.length());OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream");outputStream.write(buffer);outputStream.flush();} catch (IOException ex) {ex.printStackTrace();}}

数据库

jsp页面

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--Created by IntelliJ IDEA.User: ghostDate: 2022/1/5Time: 11:37To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>导出文档</title>
</head>
<body>
<%--展示查出的数据--%><table><tr><%--<c:forEach var="pioList" items="${pioList}" varStatus="s">--%><td style="padding-left: 40px">商品名称</td><td style="padding-left: 50px">商品价格(单位:元/斤)</td><td style="padding-left: 50px">商品库存(单位:吨)</td><%--</c:forEach>--%></tr></table><ul style="list-style:none;"><c:forEach var="pioList" items="${pioList}" varStatus="s"><li style="display: inline; padding-left: 10px; color: fuchsia">${pioList.pname}</li><li style="display: inline; padding-left: 120px; color: #ff9fa5">${pioList.price}</li><li style="display: inline; padding-left: 200px; color: #d4af7a">${pioList.pstock}</li><li> </li></c:forEach></ul>
<%--导出为Excel表格--%>
<form action="/novel/writePio">
<%--<label for="path" style="height: 30px; color: #03bbe8">文件名 :&nbsp;</label>
<input type="text" name="path" id="path"  size="50px" style="height: 30px" placeholder="请输入文件名(以.xlsx结尾,否则导出的不是Excel格式):">--%><%--导出的默认文件名为商品信息.xlsx--%><select  name="path" id="path" style="display:none"><option>商品信息.xlsx</option></select>
<input type="submit" value="导出为Excel表格" style="width: 150px; height: 60px; margin-top: 10px; margin-left: 100px"/>
</form>
</body>
</html>

最终效果

点击“导出为Excel表格就可以导出”


Java教程:使用POI读取excel文档(根据BV1bJ411G7Aw整理)相关推荐

  1. 使用Java POI读取excel文档

    Java使用POI读取excel文档教程 一:Poi的介绍 1.简介 1.由apache公司提供 2.Java编写的免费开源的跨平台的Java API 3.提供API给Java程序对Microsoft ...

  2. poi读取Excel文档(.xls .xlsx)包含合并单元格

    例子: 结果: 开始:----------------------------------- 导入的poi <!-- https://mvnrepository.com/artifact/org ...

  3. POI 读取excel文档中输入日期格式为字符串

    通过cell.getCellStyle().getDataFormat();根据这个值进行时间.日期格式的判断: 时间格式 为了获取用户输入什么格式就显示什么格式,做以下整理: 通过对format值的 ...

  4. Java实战—POI操作Excel文档、读取、写入、合并单元格

    一.POI项目简介 POI全称 Poor Obfuscation Implementation,利用POI接口可以通过JAVA操作Microsoft office 套件工具的读写功能.官网:http: ...

  5. java后台处理excel_java后台利用Apache poi 生成excel文档提供前台下载示例

    之前在项目中会用到在java在后台把数据填入Word文档的模板来提供前台下载,为了自己能随时查看当时的实现方案及方便他人学习我写了这篇博客,访问量已经是我写的博客里第一了.于是乎我在学会用Java在后 ...

  6. java读取Excel文档 + 存入数据库

    序 在做项目的时候,我们有时想要读取Excel类型的文档,把表格里面的数据进行处理,比如把成绩Excel文档存储到数据库对应的表.而这时却不知道该如何操作,接下来我将讲解这个流程.以下面的数据为例 总 ...

  7. 使用POI读取word文档

    使用POI 读取word 文档(word 2003和2007) 最近在给客户做系统的时候,用户提出需求,要能够导入 word 文件,现在 microsoft word 有好几个版本 97.2003.2 ...

  8. python无法读取excel文字_Python帮你做Excel——读取Excel文档

    相信很多坐在办公室上班的朋友每天都需要处理大量的数据,我们常常用Excel制作电子表格来帮助我们处理它们.这当然是一种非常好的做法,但是我相信大家都会发现,很多表格的内容其实大同小异,常常需要我们把同 ...

  9. 关于poi读取word文档修改后输出乱码问题 poi word 乱码

    java用poi读取word文档的确很容易.不过不同版本之间差别还是挺大的.目前只是试出了poi-3.8-beta4这个版本编辑word内容后输出不是乱码.最新官方版本都是乱码,不知道为什么.贴出代码 ...

最新文章

  1. 第80节:Java中的MVC设计模式
  2. SAP UI5 Tools 使用简介
  3. “约见”面试官系列之常见面试题之第四十五篇CSS优先级(建议收藏)
  4. bulma.css_如何建立一个? Bulma CSS的自适应博客设计
  5. html注释的内容如何修改,如何用自定义元素替换HTML注释
  6. MySQL 一张表中两个字段值互换
  7. 莫代尔是什么?它有哪些优缺点?
  8. React redux
  9. mongodb数据库的启动和停止
  10. linux 信号 --- 产生 阻塞 捕捉
  11. 编程器测试软件,CH341A编程器
  12. 数分下(第2讲):二阶线性微分方程的解法
  13. 服务器文件传输抓包,Post入门篇 第12课multipart/form-data多部件上传抓包分析过程...
  14. PNP : Work Cound Frequence
  15. genymotion配置android模拟器
  16. 数量积、向量积、混合积
  17. 【题解】【中国大学MOOC】(北京大学)人工智能与信息社会测验——8人工智能与人类社会未来
  18. 软件设计学习笔记1_架构
  19. 华为也无奈,P20pro降到历史新低价,老用户:买太早
  20. 汉字转换为拼音的函数

热门文章

  1. 人之间的尊重是相互的_人与人之间彼此尊重是相互的,你若敬我一尺,我必敬你一丈...
  2. 计算机二级C语言考试地点,最新计算机二级《C语言》重要考点
  3. 网易患病员工被保安赶出公司,项目经理该如何应对中年危机?
  4. [转载]用树莓派3配置成无线路由器
  5. 曝光补偿,白增黑减理论
  6. 蒙特卡洛python求解派_用蒙特卡洛方法计算派-python和R语言
  7. 自言自语(二)--英文无衬线体和有衬线体
  8. pyecharts绘制日历图、漏斗图、仪表盘、水滴图
  9. 海尔微型计算机硬盘如何拆卸,海尔xqb507288拆解图
  10. EFR32上实现精确的软件延时