Java使用POI读取excel文档教程

一:Poi的介绍

1.简介

1.由apache公司提供

2.Java编写的免费开源的跨平台的Java API

3.提供API给Java程序对Microsoft Office格式档案读和写的功能

2.使用前提(Java Dependency)

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

3.Poi包结构

HSSF——读写Microsoft Excel XLS

XSSF——读写Microsoft Excel XLSX

HWPF——读写Microsoft Word DOC

HLSF——提供读写Microsoft PowerPoint

4.优劣势

Jxl:消耗小、图形和图片支持有限

Poi:功能更加完善

二:Poi入门案例

Poi封装的对象:

XSSFWorkbook:工作簿
XSSFSheet:工作表
Row:行
Cell:单元格

java poi excel 设置图片浮动 java poi操作excel_List

1.从Excel文件读取数据

第一步:准备一个Excel文件(hello.xlsx)

java poi excel 设置图片浮动 java poi操作excel_bc_02

第二步:导入依赖

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

第三步:Java代码

public class Demo1 {

    public static void main(String[] args) throws IOException {
        //1、获取工作簿
        XSSFWorkbook workbook = new XSSFWorkbook("D:\\hello.xlsx");
        //2、获取工作表
        XSSFSheet sheet = workbook.getSheetAt(0);
        //3、获取行
        for (Row row : sheet) {
            //4、获取单元格
            for (Cell cell : row) {
                //5、获取单元格中的内容
                String value = cell.getStringCellValue();
                System.out.println(value);
            }
        }
        //释放资源
        workbook.close();
    }
}

另:使用普通for循环

//开始索引 0 结束索引
        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 value = cell.getStringCellValue();
                        System.out.println(value);
                    }
                }
            }
        }

第四步:控制台输出结果

Hello
World
!

Process finished with exit code 0

2.向Excel文件写入数据

第一步:Java代码

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //1、创建工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        //2、创建工作表
        XSSFSheet sheet = workbook.createSheet("工作表一");
        //3、创建行
        XSSFRow row = sheet.createRow(0);
        //4、创建单元格
        row.createCell(0).setCellValue("Hello");
        row.createCell(1).setCellValue("world");
        row.createCell(2).setCellValue("!");

        XSSFRow row1 = sheet.createRow(1);
        row1.createCell(0).setCellValue("你好");
        row1.createCell(1).setCellValue("世界");
        row1.createCell(2).setCellValue("!");

        //输出流
        FileOutputStream out = new FileOutputStream("D:\\test.xlsx");
        workbook.write(out);
        out.flush();

        //释放资源
        out.close();
        workbook.close();

        System.out.println("写入成功");
    }
}

第二步:控制台输出结果

写入成功

Process finished with exit code 0

第三步:查看生成的Excel文件

java poi excel 设置图片浮动 java poi操作excel_List_03

三、实战练习

目标:

读取Excel数据到数据库
将数据库数据写到Excel
增加样式

第一步:准备一个product.xslx

java poi excel 设置图片浮动 java poi操作excel_bc_04

第二步:创建 product表

CREATE TABLE `product` (
  `pid` int(10) NOT NULL COMMENT '商品id',
  `pname` varchar(255) NOT NULL COMMENT '商品名称',
  `price` double(10,2) NOT NULL COMMENT '商品价格',
  `pstock` int(255) NOT NULL COMMENT '商品库存',
  PRIMARY KEY (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

第三步:导入 maven依赖

<dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.20</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.6</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>

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

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.6</version>
    </dependency>

第四步:创建 JDBCUtils.java 工具类

public class JDBCUtils {

    private static DruidDataSource dataSource = null;

    static {
        Properties properties = new Properties();
        try {
            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("druid.properties"));
            dataSource = new DruidDataSource();
            dataSource.setDriverClassName(properties.getProperty("jdbc.driver"));
            dataSource.setUrl(properties.getProperty("jdbc.url"));
            dataSource.setUsername(properties.getProperty("jdbc.username"));
            dataSource.setPassword(properties.getProperty("jdbc.password"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static DruidDataSource getDataSource() {
        return dataSource;
    }

}

第五步:编写 druid.properties 配置文件

jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
jdbc.driver=com.mysql.jdbc.Driver

第六步:创建实体类 Product.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
    private Integer pid;
    private String pname;
    private double price;
    private int pstock;
}

第七步:编写业务逻辑层 ProductService.java

public interface ProductService {
    void save(List<Product> productList);
    List<Product> findAll();
}

第八步:编写业务逻辑层实现类 ProductServiceImpl.java

public class ProductServiceImpl implements ProductService {

    private ProductDao productDao = new ProductDaoImpl();

    @Override
    public void save(List<Product> productList) {
        for (Product product : productList) {
            productDao.save(product);
        }
    }

    @Override
    public List<Product> findAll() {
        return productDao.findAll();
    }
}

第九步:编写数据持久层 ProductDao.java

public interface ProductDao {
    void save(Product product);
    List<Product> findAll();
}

第十步:编写数据持久层实现类 ProductDaoImpl.java

public class ProductDaoImpl implements ProductDao {

    private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

    @Override
    public void save(Product product) {
        String sql = "insert into product values(?,?,?,?)";
        jdbcTemplate.update(sql, product.getPid(), product.getPname(), product.getPrice(), product.getPstock());
    }

    @Override
    public List<Product> findAll() {
        String sql = "select * from product";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<Product>(Product.class));
    }
}

最后一步:编写控制台 ConsoleView.java

public class ConsoleView {

    public static void main(String[] args) throws IOException {
        ProductService productService = new ProductServiceImpl();
        //通过键盘录入Scanner
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你要选择的功能:1.导入 2.导出");
        int num = sc.nextInt();
        if (num == 1) {
            //1、导入
            //1.1、读取excel表格中的数据
            System.out.println("请输入您要读取文件的位置(不包含空格)");
            String path = sc.next();
            List<Product> productList = read(path);
            //1.2、将数据写入数据库中
            productService.save(productList);
            System.out.println("数据已存入数据库中");
        } else if (num == 2) {
            //2、导出
            //2.1、读取数据库中的数据
            List<Product> productList = productService.findAll();
            //2.2、将数据写入到excel表格中
            System.out.println("请输入要写入的文件位置");
            String path = sc.next();
            write(productList, path);
            System.out.println("写入成功");
        } else {
            System.out.println("输入有误,请重新启动");
        }
    }

    public static void write(List<Product> productList, String path) throws IOException {
        //创建工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        //创建工作表
        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());//设置字体颜色
        cellStyle.setFont(font);//将字体放入样式

        //创建行
        XSSFRow row = sheet.createRow(0);
        /*row.createCell(0).setCellValue("商品编号");
        row.createCell(1).setCellValue("商品名称");
        row.createCell(2).setCellValue("商品价格(单位:元/斤)");
        row.createCell(3).setCellValue("商品库存(单位:吨)");*/

        XSSFCell cell = row.createCell(0);
        cell.setCellStyle(cellStyle);
        cell.setCellValue("商品编号");

        XSSFCell cell1 = row.createCell(1);
        cell1.setCellStyle(cellStyle);
        cell1.setCellValue("商品名称");

        XSSFCell cell2 = row.createCell(2);
        cell2.setCellStyle(cellStyle);
        cell2.setCellValue("商品价格(单位:元/斤)");

        XSSFCell cell3 = row.createCell(3);
        cell3.setCellStyle(cellStyle);
        cell3.setCellValue("商品库存(单位:吨)");

        for (int i = 0; i < productList.size(); i++) {
            XSSFRow sheetRow = sheet.createRow(i + 1);
            sheetRow.createCell(0).setCellValue(productList.get(i).getPid());
            sheetRow.createCell(1).setCellValue(productList.get(i).getPname());
            sheetRow.createCell(2).setCellValue(productList.get(i).getPrice());
            sheetRow.createCell(3).setCellValue(productList.get(i).getPstock());
        }

        FileOutputStream fileOutputStream = new FileOutputStream(path);
        workbook.write(fileOutputStream);

        fileOutputStream.flush();
        fileOutputStream.close();
        workbook.close();
    }

    public static List<Product> read(String path) throws IOException {
        List<Product> productList = new ArrayList<>();
        //获取工作簿
        XSSFWorkbook workbook = new XSSFWorkbook(path);
        //获取工作表
        XSSFSheet sheet = workbook.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<>();
                for (Cell cell : row) {
                    if (cell != null) {
                        cell.setCellType(Cell.CELL_TYPE_STRING);//设置单元格中的数据格式
                        String value = cell.getStringCellValue();
                        if (value != null && !"".equals(value)) {
                            list.add(value);
                        }
                    }
                }
                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;
    }
}

运行结果:

读:

请输入你要选择的功能:1.导入 2.导出
1
请输入您要读取文件的位置(不包含空格)
D:\product.xlsx
数据已存入数据库中

Process finished with exit code 0

写:

请输入你要选择的功能:1.导入 2.导出
2
请输入要写入的文件位置
D:\Goods.xlsx
写入成功

Process finished with exit code 0

java poi excel 设置图片浮动 java poi操作excel_poi_05

四、总结

1、在读写Excel表格中数据时,一定要先设置单元格中的数据格式

if (cell != null) {
    cell.setCellType(Cell.CELL_TYPE_STRING);//设置单元格中的数据格式
    String value = cell.getStringCellValue();
    if (value != null && !"".equals(value)) {
        list.add(value);
    }
}