700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 手摸手教学-利用原生POI对excel的导入导出以及阿里的easyexcel的基本操作

手摸手教学-利用原生POI对excel的导入导出以及阿里的easyexcel的基本操作

时间:2021-03-22 22:23:40

相关推荐

手摸手教学-利用原生POI对excel的导入导出以及阿里的easyexcel的基本操作

文章目录

原生POI对excel的导入导出以及阿里的easyexcel的基本操作首先是最原始的POI操作excel其次是POI操作excel对数据库的导入导出最后是阿里的easyexcel的简单操作([官方文档](/easyexcel/doc/read)已经十分详细 )

原生POI对excel的导入导出以及阿里的easyexcel的基本操作

首先是最原始的POI操作excel

创建一个普通的maven项目

导入pom的依赖

<dependencies><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></dependencies>

在main/java下创建包com.test.read和com.test.write

在write包下创建DemoWrite类,写入以下代码

03版本的excel最多只能存65535行数据07版的无限制HSSF是把所有数据先全部写入缓存,然后再对数据操作,写入磁盘。速度快,但是只能存65535行XSSF可以写入的数据无限制,但是操作大数据量的时候速度慢,容易内存溢出。报OOM错误SXSSF super XSSF的意思。默认100条(可配置)存入缓存,如果超出100条,最前面的数据会被写入临时文件。速度快,占内存少。再操作数据。但是仍然可能存在消耗大量内存的情况,比如合并区域、注释。。等

package com.baidu.write;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.xssf.streaming.SXSSFWorkbook;import org.apache.poi.xssf.usermodel.XSSFRow;import org.apache.poi.xssf.usermodel.XSSFSheet;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream;import java.io.IOException;public class DemoWrite {public static void main(String[] args) throws IOException {//1.创建工作簿// XSSFWorkbook workbook = new HSSFWorkbook();//操作03版本的excel 后缀为xls的文件XSSFWorkbook workbook = new XSSFWorkbook();//操作07版本的excel 后缀为xlsx的文件// XSSFWorkbook workbook = new SXSSFWorkbook();//操作升级版的07版本的excel 后缀为xlsx的文件//2.创建工作表XSSFSheet sheet = workbook.createSheet("sheetName");//3.创建行XSSFRow row = sheet.createRow(0);//3.1创建单元格row.createCell(0).setCellValue("卡特琳娜");row.createCell(1).setCellValue("不详之刃");row.createCell(2).setCellValue("中单");//创建单元格XSSFRow row1 = sheet.createRow(1);row1.createCell(0).setCellValue("放逐之刃");row1.createCell(1).setCellValue("瑞文");row1.createCell(2).setCellValue("上单");//输出流FileOutputStream fileOutputStream = new FileOutputStream("D:\\demo.xlsx");workbook.write(fileOutputStream);fileOutputStream.flush();//释放资源fileOutputStream.close();workbook.close();System.out.println("写入成功");}}

读取excel,在read包下创建DemoRead类,写入以下代码

package com.baidu.read;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.xssf.usermodel.XSSFCell;import org.apache.poi.xssf.usermodel.XSSFRow;import org.apache.poi.xssf.usermodel.XSSFSheet;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.IOException;public class DemoRead {public static void main(String[] args) throws IOException {//1.获取工作簿XSSFWorkbook workbook = new XSSFWorkbook("D:\\demo.xlsx");//2.获取工作表XSSFSheet sheet = workbook.getSheetAt(0);//获取第一个sheet//3.获取行号--增强for循环 先遍历行,然后遍历获取每一个单元格// for (Row row : sheet) {System.out.println(row);// for (Cell cell : row) {////获取单元格对象//String value = cell.getStringCellValue();//System.out.println(value);// }// }//3.获取行号 普通for循环int lastRowNum = sheet.getLastRowNum();for (int i = 0; i <= lastRowNum; i++) {XSSFRow row = sheet.getRow(i);if (row != null) {short lastCellNum = row.getLastCellNum();for (int j = 0; j <= lastCellNum; j++) {XSSFCell cell = row.getCell(j);if (cell != null) {String stringCellValue = cell.getStringCellValue();System.out.println(stringCellValue);}}}}//释放资源workbook.close();}}

其次是POI操作excel对数据库的导入导出

创建一个普通的maven项目

导入pom文件中的包

<dependencies><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><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.26</version><scope>compile</scope></dependency><!--druid连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.9</version></dependency><!--jdbcTemplate--><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>4.1.2.RELEASE</version><scope>compile</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>4.1.2.RELEASE</version><scope>compile</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>compile</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-nop</artifactId><version>1.7.2</version></dependency></dependencies>

创建数据库和数据表

-- 创建数据库CREATE DATABASE `excel` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci';-- 创建数据表CREATE TABLE `product` (`pid` int(10) unsigned NOT NULL AUTO_INCREMENT,`pname` varchar(255) NOT NULL,`price` decimal(10,2) DEFAULT NULL,`pstock` int(10) DEFAULT NULL,PRIMARY KEY (`pid`)) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;

在main-java下分别创建包 dao(操作数据库)、domain(数据表实体类)、service(服务层)、utils(工具类包)、web包。再在dao和service包下分别创建Impl包(去实现dao和service层的接口)

在resources下创建druid.properties配置文件,代码如下

driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql:///excelusername=rootpassword=rootinitialSize=5maxActive=10maxWait=3000

在utils下创建JDBCUtils工具类,代码如下

package com.baidu.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;/*** JDBC工具类 使用Durid连接池*/public class JDBCUtils {private static DataSource ds;static {try {//1.加载配置文件Properties pro = new Properties();//使用ClassLoader加载配置文件,获取字节输入流InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");pro.load(is);//2.初始化连接池对象ds = DruidDataSourceFactory.createDataSource(pro);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 获取连接池对象*/public static DataSource getDataSource() {return ds;}/*** 获取连接Connection对象*/public static Connection getConnection() throws SQLException {return ds.getConnection();}}

在domain下创建并编写Product类,如下 要记得创建全参构造和无参构造方法

package com.baidu.domain;public class Product {private Integer pid;private String pname;private Double price;private Integer pstock;//全参构造public Product(Integer pid, String pname, Double price, Integer pstock) {this.pid = pid;this.pname = pname;this.price = price;this.pstock = pstock;}//无参构造 很重要public Product() {}@Overridepublic String toString() {return "Product{" +"pid=" + pid +", pname='" + pname + '\'' +", price=" + price +", pstock=" + pstock +'}';}public Integer getPid() {return pid;}public void setPid(Integer pid) {this.pid = pid;}public String getPname() {return pname;}public void setPname(String pname) {this.pname = pname;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;}public Integer getPstock() {return pstock;}public void setPstock(Integer pstock) {this.pstock = pstock;}}

在web下创建类Show,(这里没有前端页面,用Scanner模拟)代码如下:

package com.baidu.web;import com.baidu.domain.Product;import com.baidu.service.Impl.ProductServiceImpl;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.CellStyle;import org.apache.poi.ss.usermodel.IndexedColors;import org.apache.poi.xssf.usermodel.*;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.Scanner;public class Show {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.导入//2.读取excel表格中的内容System.out.println("请输入您要读取的文件位置(不包含空格)");String path = scanner.next();List<Product> ProductList = read(path);//3.将数据写入数据库ProductServiceImpl productService = new ProductServiceImpl();productService.save(ProductList);System.out.println("数据已存入数据库中");} else if (num == 2) {//1.导出//2.读取数据库中的数据ProductServiceImpl productService = new ProductServiceImpl();List<Product> productList = productService.findAll();System.out.println(productList);//3.将数据写入excel表格中System.out.println("请输入要写入的文件位置");String path = scanner.next();write(productList,path);System.out.println("写入成功");} else {System.out.println("输入有误,请重新启动");}}//读取数据插入数据库public static List<Product> read(String path) throws IOException {List<Product> ProductList = new ArrayList<Product>();//1.获取工作簿XSSFWorkbook xssfWorkbook = new XSSFWorkbook(path);//2.获取工作表XSSFSheet sheet = xssfWorkbook.getSheetAt(0);int lastRowNum = sheet.getLastRowNum();for (int i = 1; i < lastRowNum; i++) {XSSFRow row = sheet.getRow(i);if (row != null) {List<String> list = new ArrayList<String>();//定义list集合for (Cell cell : row) {if (cell != null) {//首先设置成字符串类型 防止调用getStringCellValue方法的时候出现类型转换异常cell.setCellType(Cell.CELL_TYPE_STRING);String value = cell.getStringCellValue();//获取数据if (value != null && !"".equals(value)) {list.add(value);//数据放入list集合}}}if (list.size() > 0) {Product product = new Product(Integer.parseInt(list.get(0)), list.get(1), Double.parseDouble(list.get(2)), Integer.parseInt(list.get(3)));ProductList.add(product);}}}return ProductList;}//导出excel表格public static List<Product> write(List<Product> productList,String path) throws IOException {//1.创建工作簿XSSFWorkbook workbook = new XSSFWorkbook();//2.创建工作表XSSFSheet sheet = workbook.createSheet("商品");//设置样式XSSFCellStyle cellStyle = workbook.createCellStyle();cellStyle.setFillForegroundColor(IndexedColors.PINK.getIndex());// cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);//字体样式XSSFFont font = workbook.createFont();font.setFontName("楷体");font.setColor(IndexedColors.BLUE.getIndex());//3.创建行XSSFRow row = sheet.createRow(0);XSSFCell cell = row.createCell(0);cell.setCellValue("商品编号");cell.setCellStyle(cellStyle);XSSFCell cell1 = row.createCell(1);cell1.setCellValue("商品名称");cell1.setCellStyle(cellStyle);XSSFCell cell2 = row.createCell(2);cell2.setCellValue("商品价格(单位:元/斤)");cell2.setCellStyle(cellStyle);XSSFCell cell3 = row.createCell(3);cell3.setCellValue("商品库存(单位:吨)");cell3.setCellStyle(cellStyle);for (int i = 0; i < productList.size(); i++) {XSSFRow row1 = sheet.createRow(i + 1);row1.createCell(0).setCellValue(productList.get(i).getPid());row1.createCell(1).setCellValue(productList.get(i).getPname());row1.createCell(2).setCellValue(productList.get(i).getPrice());row1.createCell(3).setCellValue(productList.get(i).getPstock());}FileOutputStream fileOutputStream = new FileOutputStream(path);workbook.write(fileOutputStream);fileOutputStream.flush();fileOutputStream.close();workbook.close();return null;}}

编写service层代码。ProductService

package com.baidu.service;import com.baidu.domain.Product;import java.util.List;public interface ProductService {List<Product> findAll();void save(List<Product> productList);}

编写service下的Impl包中的ProductService实现类 ProductServiceImpl

package com.baidu.service.Impl;import com.baidu.dao.ProductDao;import com.baidu.dao.impl.ProductDaoImpl;import com.baidu.domain.Product;import com.baidu.service.ProductService;import java.util.List;public class ProductServiceImpl implements ProductService {private ProductDao productDao = new ProductDaoImpl();@Overridepublic List<Product> findAll() {return productDao.findAll();}@Overridepublic void save(List<Product> productList) {for (Product product : productList) {productDao.save(product);}}}

编写dao层下的ProductDao

package com.baidu.dao;import com.baidu.domain.Product;import java.util.List;public interface ProductDao {void save(Product product);List<Product> findAll();}

编写dao层下的Impl包中的ProductDao的实现类 ProductDaoImpl

package com.baidu.dao.impl;import com.baidu.dao.ProductDao;import com.baidu.domain.Product;import com.baidu.utils.JDBCUtils;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import java.util.List;public class ProductDaoImpl implements ProductDao {JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());@Overridepublic void save(Product product) {String sql = " INSERT INTO product (pid,pname,price,pstock) VALUES (?,?,?,?) ";jdbcTemplate.update(sql, product.getPid(), product.getPname(), product.getPrice(), product.getPstock());}@Overridepublic List<Product> findAll() {String sql = " select * from product ";return jdbcTemplate.query(sql,new BeanPropertyRowMapper<Product>(Product.class));}}

最后是阿里的easyexcel的简单操作(官方文档已经十分详细 )

创建一个maven项目

导入依赖

<dependencies><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.0-beta2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.71</version></dependency></dependencies>

在java目录下创建包com.test.easyexcel,我这里创建的是com.baidu.domain。其实不该在domain下创建,不符合规范。

在包下创建类DemoData,代码如下

package com.baidu.domain;import com.alibaba.excel.annotation.ExcelIgnore;import com.alibaba.excel.annotation.ExcelProperty;import lombok.Data;import java.util.Date;@Datapublic class DemoData {//easyExcel@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题")private Date date;@ExcelProperty("数字标题")private Double doubleData;//忽略这个字段@ExcelIgnoreprivate String ignore;}

创建DemoDataListener类,代码如下

package com.baidu.domain;import com.alibaba.excel.context.AnalysisContext;import com.alibaba.excel.event.AnalysisEventListener;import com.alibaba.fastjson.JSON;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.ArrayList;import java.util.List;// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去public class DemoDataListener extends AnalysisEventListener<DemoData> {private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);/*** 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 5;List<DemoData> list = new ArrayList<DemoData>();/*** 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。*/private DemoDAO demoDAO;public DemoDataListener() {// 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数demoDAO = new DemoDAO();}/*** 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来** @param demoDAO*/public DemoDataListener(DemoDAO demoDAO) {this.demoDAO = demoDAO;}/*** 这个每一条数据解析都会来调用** @param data* one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context*/@Overridepublic void invoke(DemoData data, AnalysisContext context) {System.out.println(JSON.toJSONString(data));// LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));//未导入LOGGER.info的配置文件 所以用System.out.println输出list.add(data);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (list.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listlist.clear();}}/*** 所有数据解析完成了 都会来调用** @param context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库saveData();LOGGER.info("所有数据解析完成!");}/*** 加上存储数据库*/private void saveData() {LOGGER.info("{}条数据,开始存储数据库!", list.size());demoDAO.save(list);LOGGER.info("存储数据库成功!");}}

创建DemoDAO,代码如下

package com.baidu.domain;import java.util.List;/*** 假设这个是你的DAO存储。当然还要这个类让spring管理,当然你不用需要存储,也不需要这个类。**/public class DemoDAO {public void save(List<DemoData> list) {// 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入}}

在utils包下面创建TestFileUtil工具类。就获取文件路径之类的东西 跳过这一步也没啥影响。因为第8步已经注释掉了相关代码。

package com.baidu.utils;import java.io.File;import java.io.InputStream;public class TestFileUtil {public static InputStream getResourcesFileInputStream(String fileName) {return Thread.currentThread().getContextClassLoader().getResourceAsStream("" + fileName);}public static String getPath() {return TestFileUtil.class.getResource("/").getPath();}public static File createNewFile(String pathName) {File file = new File(getPath() + pathName);if (file.exists()) {file.delete();} else {if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}}return file;}public static File readFile(String pathName) {return new File(getPath() + pathName);}public static File readUserHomeFile(String pathName) {return new File(System.getProperty("user.home") + File.separator + pathName);}}

创建测试类,代码如下。跑每个测试方法即可测试。

import com.alibaba.excel.EasyExcel;import com.alibaba.excel.ExcelReader;import com.alibaba.excel.ExcelWriter;import com.alibaba.excel.read.metadata.ReadSheet;import com.alibaba.excel.write.metadata.WriteSheet;import com.baidu.domain.DemoData;import com.baidu.domain.DemoDataListener;import com.baidu.utils.TestFileUtil;import org.junit.Test;import java.io.File;import java.util.ArrayList;import java.util.Date;import java.util.List;public class TestEasyExcel {String PATH = "D:\\";private List<DemoData> data() {List<DemoData> list = new ArrayList<DemoData>();for (int i = 0; i < 10; i++) {DemoData data = new DemoData();data.setString("字符串" + i);data.setDate(new Date());data.setDoubleData(0.56);list.add(data);}return list;}//根据list,写入excel@Testpublic void simpleWrite() {//写法1String fileName = PATH + "easy.xlsx";EasyExcel.write(fileName, DemoData.class).sheet("zls").doWrite(data());System.out.println("执行完毕");}/*** 官方文档提供的方法* 最简单的写* <p>1. 创建excel对应的实体对象 参照{@link DemoData}* <p>2. 直接写即可*/@Testpublic void simpleWriteDemo() {// 写法1String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());// 写法2fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";// 这里 需要指定写用哪个class去写ExcelWriter excelWriter = null;try {excelWriter = EasyExcel.write(fileName, DemoData.class).build();WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();excelWriter.write(data(), writeSheet);} finally {// 千万别忘记finish 会帮忙关闭流if (excelWriter != null) {excelWriter.finish();}}}/*** 官方文档提供的方法* 最简单的读* <p>1. 创建excel对应的实体对象 参照{@link DemoData}* <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}* <p>3. 直接读即可*/@Testpublic void simpleRead() {// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去// 写法1:// String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";String fileName = PATH + "easy.xlsx";//路径使用刚才写出来的文件// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();// 写法2:不做测试// fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// ExcelReader excelReader = null;// try {// excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build();// ReadSheet readSheet = EasyExcel.readSheet(0).build();// excelReader.read(readSheet);// } finally {// if (excelReader != null) {//// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的//excelReader.finish();// }// }}}

参考教程:

狂神说

传智博学谷–(这是一个小姐姐的教程,值得看看)

其实这也不是教学博客,只是自己看完别人的教程以后的一个总结而已。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。