Apache POI入门学习

Apache POI入门学习

官网地址

https://poi.apache.org/index.html

Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。POI为"Poor Obfuscation Implementation"的首字母缩写,意为"简洁版的模糊实现"。

excel中使用到的类

一个excel表格文件包含一个工作簿,一个工作簿包含多个工作表,每个工作表包含多个行,每行包含多个单元格。

读取excel表格内容

表格内容

maven依赖

markup 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.example</groupId>
    <artifactId>ApachePoi-Demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!--poi 是基础依赖,提供了操作 Excel 文件的核心功能-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.5</version>
        </dependency>
        <!--poi-ooxml 是操作 Office Open XML 格式文件(如 .xlsx、.docx 等)的扩展库。-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.5</version>
        </dependency>
        <!--spring web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--spring boot单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.1.2</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

方式一

for循环的方式读取数据

java 复制代码
package com.apache.poi.demo.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.apache.poi.ss.usermodel.CellType;
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 org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

@RestController
public class DemoController {

    @PostMapping(value = "/poi/excel/import")
    public void excelImport(@RequestParam("file") MultipartFile file) throws Exception {
        // 输入流
        InputStream inputStream = file.getInputStream();
        // 创建一个工作簿
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
        // 获取工作表getSheetAt,索引从0开始表示第一个工作表
        XSSFSheet sheet = workbook.getSheetAt(0);
        // 获取工作表中对应的行数
        int rows = sheet.getLastRowNum();
        for (int r = 0; r <= rows; r++) {
            // 获取指定的行
            XSSFRow row = sheet.getRow(r);
            // 获取指定的行数所对应的单元格
            int cols = sheet.getRow(r).getLastCellNum();
            for (int c = 0; c < cols; c++) {
                // 获取指定行指定的单元格
                XSSFCell cell = row.getCell(c);
                // 单元格类型,可以是字符串也可以是数字,也可以是布尔值
                CellType cellType = cell.getCellType();
                switch (cellType) {
                    case STRING -> {
                        // 字符串类型获取对应的字符串值
                        System.out.print(cell.getStringCellValue());
                        break;
                    }
                    case NUMERIC -> {
                        // 数字类型获取对应的数字
                        System.out.print(cell.getNumericCellValue());
                        break;
                    }
                    case BOOLEAN -> {
                        // 布尔类型获取对应的布尔值
                        System.out.print(cell.getBooleanCellValue());
                        break;
                    }
                }
                System.out.print(" | ");
            }
            System.out.println();
        }
    }
}

测试结果


方式二

使用Iterator进行遍历表格数据

java 复制代码
package com.apache.poi.demo.controller;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
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 org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.Iterator;

@RestController
public class DemoTwoController {

    @PostMapping(value = "/poi/excel/import2")
    public void excelImportTwo(@RequestParam("file") MultipartFile file) throws Exception {
        // 输入流
        InputStream inputStream = file.getInputStream();
        // 创建一个工作簿
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
        // 获取工作表getSheetAt,索引从0开始表示第一个工作表
        XSSFSheet sheet = workbook.getSheetAt(0);
        Iterator<Row> rowIterator = sheet.rowIterator();
        while (rowIterator.hasNext()) {
            // 获取指定的行
            XSSFRow row = (XSSFRow) rowIterator.next();
            // 获取单元格
            Iterator<Cell> cellIterator = row.cellIterator();
            while (cellIterator.hasNext()) {
                XSSFCell cell = (XSSFCell) cellIterator.next();
                CellType cellType = cell.getCellType();
                switch (cellType) {
                    // 字符串类型获取对应的字符串值
                    case STRING -> System.out.print(cell.getStringCellValue());
                    // 数字类型获取对应的数字
                    case NUMERIC -> System.out.print(cell.getNumericCellValue());
                    //布尔类型获取对应的布尔值
                    case BOOLEAN -> System.out.print(cell.getBooleanCellValue());
                }
                System.out.print(" | ");
            }
            System.out.println();
        }
    }
}

测试结果


向excel中写入数据

方式一

通过使用for循环的方式向excel中写入数据

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 向excel中写入数据的步骤
 * Workbook -> Sheet -> Rows -> Cells
 */
public class WriteExcelDemo {
    public static void main(String[] args) throws IOException {
        // 创建工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 工作表名称为Emp Info
        XSSFSheet sheet = workbook.createSheet("Emp Info");
        Object empdata[][] = {
                {"EmpID", "Name", "Job"},
                {101, "David", "Enginner"},
                {102, "Smith", "Manager"},
                {103, "Scott", "Analyst"}
        };
        for (int r = 0; r < empdata.length; r++) {
            // 创建表格行
            XSSFRow row = sheet.createRow(r);
            for (int c = 0; c < empdata[r].length; c++) {
                // 创建单元格
                Cell cell = row.createCell(c);
                Object value = empdata[r][c];
                // 判断值的类型,然后进行转换
                if (value instanceof String) {
                    cell.setCellValue((String) value);
                } else if (value instanceof Integer) {
                    cell.setCellValue((Integer) value);
                } else if (value instanceof Boolean) {
                    cell.setCellValue((Boolean) value);
                }
            }
        }
        File dir = new File(".\\datafiles");
        if (!dir.exists()) {
            // 文件夹不存在则自动创建
            dir.mkdir();
        }
        String filePath = ".\\datafiles\\employee.xlsx";
        // new FileOutputStream(filePath, true);true表示文件不存在时候,自动生成
        FileOutputStream fileOutputStream = new FileOutputStream(filePath, true);
        workbook.write(fileOutputStream);

        // 关闭流
        workbook.close();
        fileOutputStream.close();
        System.out.println("employee.xlsx写入成功");
    }
}

方式二

java 复制代码
package com.apache.poi.demo;

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.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 向excel中写入数据的步骤
 * Workbook -> Sheet -> Rows -> Cells
 */
public class WriteExcelDemo2 {
    public static void main(String[] args) throws IOException {
        // 创建工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 工作表名称为Emp Info
        XSSFSheet sheet = workbook.createSheet("Emp Info");
        Object empdata[][] = {
                {"EmpID", "Name", "Job"},
                {101, "David", "Enginner"},
                {102, "Smith", "Manager"},
                {103, "Scott", "Analyst"}
        };
        int rowCount = 0;
        // 数据存储在一维数组emp[]中,
        for (Object emp[] : empdata) {
            // rowCount++,每次值使用之后,自动加1
            XSSFRow row = sheet.createRow(rowCount++);
            int columnCount = 0;
            for (Object value : emp) {
                XSSFCell cell = row.createCell(columnCount++);
                // 判断值的类型,然后进行转换
                if (value instanceof String) {
                    cell.setCellValue((String) value);
                } else if (value instanceof Integer) {
                    cell.setCellValue((Integer) value);
                } else if (value instanceof Boolean) {
                    cell.setCellValue((Boolean) value);
                }
            }
        }

        File dir = new File(".\\datafiles");
        if (!dir.exists()) {
            // 文件夹不存在则自动创建
            dir.mkdir();
        }
        // 写入当前项目下的datafiles目录下的employee.xlsx
        String filePath = ".\\datafiles\\employee.xlsx";
        // new FileOutputStream(filePath, true);true表示文件不存在时候,自动生成
        FileOutputStream fileOutputStream = new FileOutputStream(filePath, true);
        workbook.write(fileOutputStream);

        // 关闭流
        workbook.close();
        fileOutputStream.close();
        System.out.println("employee.xlsx写入成功");
    }
}

方式三

java 复制代码
package com.apache.poi.demo;

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.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 向excel中写入数据的步骤
 * Workbook -> Sheet -> Rows -> Cells
 */
public class WriteExcelDemo3 {
    public static void main(String[] args) throws IOException {
        // 创建工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 工作表名称为Emp Info
        XSSFSheet sheet = workbook.createSheet("Emp Info");

        ArrayList<Object[]> empData = new ArrayList<>();
        empData.add(new Object[]{"EmpID", "Name", "Job"});
        empData.add(new Object[]{101, "David", "Enginner"});
        empData.add(new Object[]{102, "Smith", "Manager"});
        empData.add(new Object[]{103, "Scott", "Analyst"});


        int rowNum = 0;
        for (Object[] emp : empData) {
            XSSFRow row = sheet.createRow(rowNum++);
            int cellNum = 0;
            for (Object value : emp) {
                XSSFCell cell = row.createCell(cellNum++);
                // 判断值的类型,然后进行转换
                if (value instanceof String) {
                    cell.setCellValue((String) value);
                } else if (value instanceof Integer) {
                    cell.setCellValue((Integer) value);
                } else if (value instanceof Boolean) {
                    cell.setCellValue((Boolean) value);
                }
            }
        }

        // 写入当前项目下的datafiles目录下的employee.xlsx
        String filePath = ".\\datafiles\\employee.xlsx";
        // new FileOutputStream(filePath, true);true表示文件不存在时候,自动生成
        FileOutputStream fileOutputStream = new FileOutputStream(filePath, true);
        workbook.write(fileOutputStream);

        // 关闭流
        workbook.close();
        fileOutputStream.close();
        System.out.println("employee.xlsx写入成功");
    }
}

测试结果

方式一、方式二和方式三的代码,都会在项目的根目录下的datafiles文件夹中生成employee.xlsx

employee.xlsx的文件内容如下

从 Excel 工作表中的公式单元格读取数据

java 复制代码
package com.apache.poi.demo;

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.FileInputStream;
import java.io.IOException;

public class ReadDataFromFormulaCell {
    public static void main(String[] args) throws IOException {
        String filePath = ".\\datafiles\\readFormula.xlsx";
        FileInputStream fileInputStream = new FileInputStream(filePath);

        XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
        XSSFSheet sheet = workbook.getSheetAt(0);

        int rows = sheet.getLastRowNum();
        int cols = sheet.getRow(0).getLastCellNum();

        for (int r = 0; r <= rows; r++) {
            XSSFRow row = sheet.getRow(r);
            for (int c = 0; c < cols; c++) {
                XSSFCell cell = row.getCell(c);
                switch (cell.getCellType()) {
                    case STRING -> System.out.print(cell.getStringCellValue());
                    case NUMERIC, FORMULA -> System.out.print(cell.getNumericCellValue());
                    case BOOLEAN -> System.out.print(cell.getBooleanCellValue());
                }
                System.out.print("|");
            }
            System.out.println();
        }

        fileInputStream.close();
    }
}


测试结果

Excel 工作表中写入公式单元格

java 复制代码
package com.apache.poi.demo;

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;

/**
 * Excel 工作表中写入公式单元格
 */
public class WriteDataFromFormulaCell {
    public static void main(String[] args) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        String sheetName = "Number";
        XSSFSheet sheet = workbook.createSheet(sheetName);
        XSSFRow row = sheet.createRow(0);

        row.createCell(0).setCellValue(10);
        row.createCell(1).setCellValue(20);
        row.createCell(2).setCellValue(30);

        /**
         * setCellFormula设置单元格公式,A1*B1*C1,单元格列名,
         * A1*B1*C1相当于单元格的值等于第一行第一个单元格乘以第一行第二个单元格乘以第一行第三个单元格
         */
        row.createCell(3).setCellFormula("A1*B1*C1");

        String filePath = ".\\datafiles\\calc.xlsx";
        // new FileOutputStream(filePath, true);true表示文件不存在,自动生成
        FileOutputStream fileOutputStream = new FileOutputStream(filePath, true);
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        workbook.close();
    }
}

生成文件

文件内容

从受密码保护的Excel中读取数据

一个excel文件,被密码进行保护,如何读取里面的数据。表格数据如下

方式一

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.ss.usermodel.WorkbookFactory;
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.FileInputStream;
import java.io.IOException;

/**
 * 从受密码保护的Excel中读取数据
 */
public class ReadingPasswordProtectedExcel {
    public static void main(String[] args) throws IOException {

        String path = ".\\datafiles\\customers.xlsx";
        FileInputStream fis = new FileInputStream(path);
        // 密码
        String password = "test123";

        // 根据可能受密码保护的给定InputStream创建适当的HSSFWorkbook/XSSFWorkbook。
        XSSFWorkbook workbook = (XSSFWorkbook) WorkbookFactory.create(fis, password);
        // 获取指定的工作表
        XSSFSheet sheet = workbook.getSheetAt(0);
        // 一共有5行数据,索引从0开始
        int rows = sheet.getLastRowNum();
        // 一共有3列,索引从1开始
        int cols = sheet.getRow(0).getLastCellNum();

        // 使用for循环读取数据
        for (int r = 0; r <= rows; r++) {
            XSSFRow row = sheet.getRow(r);
            for (int c = 0; c < cols; c++) {
                XSSFCell cell = row.getCell(c);
                switch (cell.getCellType()) {
                    case NUMERIC, FORMULA -> System.out.print(cell.getNumericCellValue());
                    case STRING -> System.out.print(cell.getStringCellValue());
                    case BOOLEAN -> System.out.print(cell.getBooleanCellValue());
                }
                System.out.print(" | ");
            }
            System.out.println();
        }

        // 关闭流
        workbook.close();
        fis.close();
    }
}

测试结果

方式二

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;

/**
 * 从受密码保护的Excel中读取数据
 */
public class ReadingPasswordProtectedExcel2 {
    public static void main(String[] args) throws IOException {
        String path = ".\\datafiles\\customers.xlsx";
        FileInputStream fis = new FileInputStream(path);
        // 密码
        String password = "test123";

        // 根据可能受密码保护的给定InputStream创建适当的HSSFWorkbook/XSSFWorkbook。
        XSSFWorkbook workbook = (XSSFWorkbook) WorkbookFactory.create(fis, password);
        // 获取指定的工作表
        XSSFSheet sheet = workbook.getSheetAt(0);

        // 使用迭代器来读取表格中的数据
        Iterator<Row> rowIterator = sheet.rowIterator();

        while (rowIterator.hasNext()) {
            Row row = rowIterator.next();
            Iterator<Cell> cellIterator = row.cellIterator();
            while (cellIterator.hasNext()) {
                Cell cell = cellIterator.next();
                switch (cell.getCellType()) {
                    case NUMERIC, FORMULA -> System.out.print(cell.getNumericCellValue());
                    case STRING -> System.out.print(cell.getStringCellValue());
                    case BOOLEAN -> System.out.print(cell.getBooleanCellValue());
                }
                System.out.print(" | ");
            }
            System.out.println();
        }
        // 关闭流
        workbook.close();
        fis.close();
    }
}

测试结果

填充背景色和前景色到单元格中

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.*;

import java.io.FileOutputStream;
import java.io.IOException;

public class FormattingCellColor {
    public static void main(String[] args) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Sheet1");
        XSSFRow row = sheet.createRow(1);

        // 设置背景色
        XSSFCellStyle style = workbook.createCellStyle();
        style.setFillBackgroundColor(IndexedColors.BRIGHT_GREEN.getIndex());
        style.setFillPattern(FillPatternType.BIG_SPOTS);

        // 创建第一个单元格
        XSSFCell cell = row.createCell(1);
        cell.setCellValue("welcome");
        cell.setCellStyle(style);

        //设置前景色
        style = workbook.createCellStyle();
        style.setFillBackgroundColor(IndexedColors.YELLOW.getIndex());
        style.setFillPattern(FillPatternType.BIG_SPOTS);

        // 创建第二个单元格
        cell = row.createCell(2);
        cell.setCellValue("Automation");
        cell.setCellStyle(style);

        String path = ".\\datafiles\\style.xlsx";
        FileOutputStream fos = new FileOutputStream(path, true);
        workbook.write(fos);
        workbook.close();
        fos.close();

        System.out.println("Done!!!");
    }
}

测试结果

生成的表格样式

将HashMap格式写入表格

java 复制代码
package com.apache.poi.demo;

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;
import java.util.HashMap;
import java.util.Map;

/**
 *
 */
public class HashMapExcel {
    public static void main(String[] args) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Student data");

        Map<String, String> data = new HashMap<>();
        data.put("101", "John");
        data.put("102", "Smith");
        data.put("103", "Scott");
        data.put("104", "Kim");
        data.put("105", "Mary");

        int rowNo = 0;
        for (Map.Entry entry : data.entrySet()) {
            XSSFRow row = sheet.createRow(rowNo++);
            row.createCell(0).setCellValue((String) entry.getKey());
            row.createCell(1).setCellValue((String) entry.getValue());
        }
        FileOutputStream fos = new FileOutputStream(".\\datafiles\\student.xlsx", true);
        workbook.write(fos);
        workbook.close();
        fos.close();

        System.out.println("Excel Written Successfully!");
    }
}

测试结果

控制台输出

从excel中读取数据到HashMap中

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 把表格数据读取到HashMap中
 */
public class ExcelToHashMap {
    public static void main(String[] args) throws IOException {
        String path = ".\\datafiles\\student.xlsx";
        FileInputStream fis = new FileInputStream(path);

        XSSFWorkbook workbook = new XSSFWorkbook(fis);
        XSSFSheet sheet = workbook.getSheet("Student data");

        int rows = sheet.getLastRowNum();
        HashMap<String, String> data = new HashMap<>();

        // 读取数据从表格到HashMap
        for (int r = 0; r <= rows; r++) {
            String key = sheet.getRow(r).getCell(0).getStringCellValue();
            String value = sheet.getRow(r).getCell(1).getStringCellValue();
            data.put(key, value);
        }

        // 读取数据从HashMap中
        for (Map.Entry entry : data.entrySet()) {
            System.out.println(entry.getKey() + " " + entry.getValue());
        }
        System.out.println(data);
        workbook.close();
        fis.close();
    }
}

测试结果

从数据库中读取数据并写入Excel

springboot的maven项目添加postgresql数据库依赖

markup 复制代码
 <!--postgresql依赖-->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
java 复制代码
package com.apache.poi.demo;

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;
import java.sql.*;

/**
 * 从数据库中读取数据并写入Excel
 */
public class DataBaseToExcel {

    /**
     * url
     */
    private static final String url = "jdbc:postgresql://localhost:5432/cps";

    /**
     * 用户名
     */
    private static final String username = "postgres";

    /**
     * 密码
     */
    private static final String password = "admin";

    public static void main(String[] args) throws SQLException, IOException {

        // 连接到数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        // statement/query
        Statement statement = connection.createStatement();
        String sql = "select * from departments";
        ResultSet rs = statement.executeQuery(sql);

        // 表格
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Locations Data");

        // 创建表格标题行

        XSSFRow row = sheet.createRow(0);
        row.createCell(0).setCellValue("department_id");
        row.createCell(1).setCellValue("department_name");
        row.createCell(2).setCellValue("manager_id");
        row.createCell(3).setCellValue("location_id");
        int rowNum = 1;
        while (rs.next()) {

            String departmentId = rs.getString("department_id");
            String departmentName = rs.getString("department_name");
            String managerId = rs.getString("manager_id");
            String locationId = rs.getString("location_id");

            row = sheet.createRow(rowNum++);

            row.createCell(0).setCellValue(departmentId);
            row.createCell(1).setCellValue(departmentName);
            row.createCell(2).setCellValue(managerId);
            row.createCell(3).setCellValue(locationId);
        }

        FileOutputStream fos = new FileOutputStream(".\\datafiles\\department.xlsx");
        workbook.write(fos);
        workbook.close();
        fos.close();
         //关闭数据库连接
        connection.close();
    }
}

测试结果

从Excel中读取数据并写入数据库表

excel内容

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;

/**
 * 从Excel中读取数据并写入数据库表
 */
public class ExcelToDatabase {

    /**
     * url
     */
    private static final String url = "jdbc:postgresql://localhost:5432/cps";

    /**
     *
     */
    private static final String username = "postgres";

    /**
     * 密码
     */
    private static final String password = "admin";

    public static void main(String[] args) throws SQLException, IOException {
        // 连接到数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        // statement/query
        Statement statement = connection.createStatement();
        String sql = "create table test.departments (department_id int4 not null,department_name varchar(30) not null,manager_id int4 null,location_id int4 null)";
        statement.execute(sql);

        // 表格
        FileInputStream fis = new FileInputStream(".\\datafiles\\department.xlsx");
        XSSFWorkbook workbook = new XSSFWorkbook(fis);
        XSSFSheet sheet = workbook.getSheet("Locations Data");

        int rows = sheet.getLastRowNum();


        for (int r = 1; r <= rows; r++) {
            XSSFRow row = sheet.getRow(r);
            double departmentId = Double.parseDouble(row.getCell(0).getStringCellValue());
            String departmentName = row.getCell(1).getStringCellValue();
            int managerId = Integer.parseInt(row.getCell(2).getStringCellValue());
            int locationId = Integer.parseInt(row.getCell(3).getStringCellValue());

            sql = "insert into test.departments values(?,?,?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setDouble(1, departmentId);
            preparedStatement.setString(2, departmentName);
            preparedStatement.setInt(3, managerId);
            preparedStatement.setInt(4, locationId);
            preparedStatement.executeUpdate();

            // 提交sql
            statement.execute("commit");
        }
        workbook.close();
        fis.close();
        connection.close();

    }
}

生成的数据表

Selenium中的数据驱动测试

maven依赖

markup 复制代码
<!--selenium的java依赖-->
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.20.0</version>
        </dependency>
         <!--TestNg的依赖-->
        <!-- https://mvnrepository.com/artifact/org.testng/testng -->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>7.10.1</version>
            <scope>test</scope>
        </dependency>

获取提交按钮的Xpath

自动化登录的地址:https://admin-demo.nopcommerce.com/login

工具类

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
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.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class XLUtility {

    public FileInputStream fis;
    public FileOutputStream fos;
    public XSSFWorkbook workbook;
    public XSSFSheet sheet;
    public XSSFRow row;
    public XSSFCell cell;
    public CellStyle style;
    String path = null;

    XLUtility(String path) {
        this.path = path;
    }

    /**
     * 获取工作表中的行数
     *
     * @param sheetName 工作表名
     * @return 表格行数
     * @throws IOException 抛出IO异常
     */
    public int getRowCount(String sheetName) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        int rowCount = sheet.getLastRowNum();
        workbook.close();
        fis.close();
        return rowCount;
    }

    /**
     * 获取工作表中行所在的单元格数量
     *
     * @param sheetName 工作表名
     * @param rowNum    表格行号
     * @return 行所在的单元格数量
     * @throws IOException 抛出IO异常
     */
    public int getCellCount(String sheetName, int rowNum) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        row = sheet.getRow(rowNum);
        int cellCount = row.getLastCellNum();
        workbook.close();
        fis.close();
        return cellCount;
    }

    /**
     * 获取单元格内容
     *
     * @param sheetName 工作表名
     * @param rowNum    表格行号
     * @param cellNum   单元格号
     * @return 单元格内容
     * @throws IOException 抛出IO异常
     */
    public String getCellData(String sheetName, int rowNum, int cellNum) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        row = sheet.getRow(rowNum);
        cell = row.getCell(cellNum);

        DataFormatter formatter = new DataFormatter();
        String data;
        try {
            data = formatter.formatCellValue(cell);
        } catch (Exception e) {
            data = "";
        }
        workbook.close();
        fis.close();
        return data;
    }

    /**
     * 设置表格单元格内容
     *
     * @param sheetName 工作表名
     * @param rowNum    表格行号
     * @param cellNum   单元格号
     * @param data      单元格内容
     * @throws IOException 抛出IO异常
     */
    public void setCellData(String sheetName, int rowNum, int cellNum, String data) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        row = sheet.getRow(rowNum);
        cell = row.getCell(cellNum);
        cell.setCellValue(data);

        fos = new FileOutputStream(path);
        workbook.write(fos);
        workbook.close();
        fis.close();
        fos.close();
    }

    /**
     * 单元格填充颜色
     *
     * @param sheetName 工作表名
     * @param rowNum    表格行号
     * @param cellNum   单元格号
     * @throws IOException 抛出IO异常
     */
    public void fillGreenColor(String sheetName, int rowNum, int cellNum) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        row = sheet.getRow(rowNum);
        cell = row.getCell(cellNum);
        style = workbook.createCellStyle();
        style.setFillForegroundColor(IndexedColors.GREEN.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cell.setCellStyle(style);
        workbook.write(fos);
        workbook.close();
        fis.close();
        fos.close();
    }
}

案例代码

java 复制代码
package com.apache.poi.demo;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class DataDriverTest {

    WebDriver driver;

    @BeforeClass
    public void setup() {
        // 将chromedriver下载放到自己的一个目录中,并在代码中设置
        System.setProperty("webdriver.chrome.driver", "..\\selenium-java-demo\\driver\\chromedriver.exe");

        //使用驱动实例并开启对话
        driver = new ChromeDriver();

        // 建立等待策略
        driver.manage().timeouts().implicitlyWait(500000, TimeUnit.SECONDS);

        // 窗口最大化
        driver.manage().window().maximize();
    }


    @Test(dataProvider = "LoginData")
    public void loginTest(String user, String pwd, String exp) {
        String url = "https://admin-demo.nopcommerce.com/login";
        // 打开的url
        driver.get(url);
        WebElement txtEmail = driver.findElement(By.id("Email"));
        // 清空元素的输入
        txtEmail.clear();
        // 输入内容
        txtEmail.sendKeys(user);

        WebElement txtPassword = driver.findElement(By.id("Password"));
        txtPassword.clear();
        txtPassword.sendKeys(pwd);

        // LOG IN按钮的Xpath陆路径
        String xPath = "/html/body/div[6]/div/div/div/div/div[2]/div[1]/div/form/div[3]/button";
        //  点击LOG IN按钮
        driver.findElement(By.xpath(xPath)).click();

        String expTitle = "Dashboard / nopCommerce administration";
        String actTitle = driver.getTitle();

        if (exp.equals("Valid")) {
            if (expTitle.equals(actTitle)) {
                driver.findElement(By.linkText("Logout")).click();
                Assert.assertTrue(true);
            } else {
                Assert.assertTrue(false);
            }
        } else if (exp.equals("Invalid")) {
            if (expTitle.equals(actTitle)) {
                driver.findElement(By.linkText("Logout")).click();
                Assert.assertTrue(false);
            } else {
                Assert.assertTrue(true);
            }
        }


    }

    /**
     * 数据提供者
     * 必须返回Object[][]数组类型
     */
    @DataProvider(name = "LoginData")
    public String[][] getData() throws IOException {
        // 从excel中获取数据
        String path = ".\\datafiles\\loginData.xlsx";
        XLUtility util = new XLUtility(path);
        int totalRows = util.getRowCount("Sheet1");
        int totalCols = util.getCellCount("Sheet1", 1);
        String loginData[][] = new String[totalRows][totalCols];
        for (int i = 1; i < totalRows; i++) {
            for (int j = 0; j < totalCols; j++) {
                String cellData = util.getCellData("Sheet1", i, j);
                loginData[i-1][j] = cellData;
            }
        }
        return loginData;
    }

    @AfterClass
    void tearDown() {
        driver.quit();
    }
}

在Selenium中将WebTable数据写入Excel表(网页数据抽取)

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
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.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class XLUtility {

    public FileInputStream fis;
    public FileOutputStream fos;
    public XSSFWorkbook workbook;
    public XSSFSheet sheet;
    public XSSFRow row;
    public XSSFCell cell;
    public CellStyle style;
    String path = null;

    XLUtility(String path) {
        this.path = path;
    }

    /**
     * 获取工作表中的行数
     *
     * @param sheetName 工作表名
     * @return 表格行数
     * @throws IOException 抛出IO异常
     */
    public int getRowCount(String sheetName) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        int rowCount = sheet.getLastRowNum();
        workbook.close();
        fis.close();
        return rowCount;
    }

    /**
     * 获取工作表中行所在的单元格数量
     *
     * @param sheetName 工作表名
     * @param rowNum    表格行号
     * @return 行所在的单元格数量
     * @throws IOException 抛出IO异常
     */
    public int getCellCount(String sheetName, int rowNum) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        row = sheet.getRow(rowNum);
        int cellCount = row.getLastCellNum();
        workbook.close();
        fis.close();
        return cellCount;
    }

    /**
     * 获取单元格内容
     *
     * @param sheetName 工作表名
     * @param rowNum    表格行号
     * @param cellNum   单元格号
     * @return 单元格内容
     * @throws IOException 抛出IO异常
     */
    public String getCellData(String sheetName, int rowNum, int cellNum) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        row = sheet.getRow(rowNum);
        cell = row.getCell(cellNum);

        DataFormatter formatter = new DataFormatter();
        String data;
        try {
            data = formatter.formatCellValue(cell);
        } catch (Exception e) {
            data = "";
        }
        workbook.close();
        fis.close();
        return data;
    }

    /**
     * 设置表格单元格内容
     *
     * @param sheetName 工作表名
     * @param rowNum    表格行号
     * @param cellNum   单元格号
     * @param data      单元格内容
     * @throws IOException 抛出IO异常
     */
    public void setCellData(String sheetName, int rowNum, int cellNum, String data) throws IOException {
        File xlFile = new File(path);
        if (!xlFile.exists()) {
            // 如果文件不存在就创建一个新文件
            workbook = new XSSFWorkbook();
            fos = new FileOutputStream(path);
            workbook.write(fos);
        }
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        if (workbook.getSheetIndex(sheetName) == -1) {
            // 工作表不存在就创建
            workbook.createSheet(sheetName);
        }
        sheet = workbook.getSheet(sheetName);
        if (sheet.getRow(rowNum) == null) {
            // 表格行不存在就创建
            row = sheet.createRow(rowNum);
        }
        row = sheet.getRow(rowNum);
        cell = row.createCell(cellNum);
        cell.setCellValue(data);

        fos = new FileOutputStream(path);
        workbook.write(fos);
        workbook.close();
        fis.close();
        fos.close();
    }

    /**
     * 单元格填充颜色
     *
     * @param sheetName 工作表名
     * @param rowNum    表格行号
     * @param cellNum   单元格号
     * @throws IOException 抛出IO异常
     */
    public void fillGreenColor(String sheetName, int rowNum, int cellNum) throws IOException {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheet(sheetName);
        row = sheet.getRow(rowNum);
        cell = row.getCell(cellNum);
        style = workbook.createCellStyle();
        style.setFillForegroundColor(IndexedColors.GREEN.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cell.setCellStyle(style);
        workbook.write(fos);
        workbook.close();
        fis.close();
        fos.close();
    }
}
java 复制代码
package com.apache.poi.demo;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 在Selenium中将WebTable数据写入Excel表(网页数据抽取)
 */
public class WebTableToExcel {
    public static void main(String[] args) throws IOException {
        //设置环境变量
        String driverPath = ".\\selenium-java-demo\\driver\\chromedriver.exe";
        System.setProperty("webdriver.chrome.driver", driverPath);

        // 使用驱动实例开启会话
        WebDriver driver = new ChromeDriver();
        //等待策略
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        // 窗口最大化
        driver.manage().window().maximize();

        //导航到的url
        String url = "https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population";
        driver.get(url);

        String path = ".\\datafiles\\population.xlsx";
        XLUtility utility = new XLUtility(path);

        // 设置标题行
        utility.setCellData("Sheet1", 0, 0, "Location");
        utility.setCellData("Sheet1", 0, 1, "Population");
        utility.setCellData("Sheet1", 0, 2, "% of world");
        utility.setCellData("Sheet1", 0, 3, "Date");
        utility.setCellData("Sheet1", 0, 4, "Source");

        // 捕获表格数据
        WebElement table = driver.findElement(By.xpath("//*[@id=\"mw-content-text\"]/div[1]/table/tbody"));
        // 在网页中表格的行
        int size = table.findElements(By.xpath("tr")).size();

        for (int r = 1; r <= size; r++) {
            String location = table.findElement(By.xpath("tr[" + r + "]/td[1]")).getText();
            String population = table.findElement(By.xpath("tr[" + r + "]/td[2]")).getText();
            String world = table.findElement(By.xpath("tr[" + r + "]/td[3]")).getText();
            String date = table.findElement(By.xpath("tr[" + r + "]/td[4]")).getText();
            String source = table.findElement(By.xpath("tr[" + r + "]/td[5]")).getText();
            System.out.println(location + " " + population + " " + world + " " + date + " " + source);

            utility.setCellData("Sheet1", r, 0, location);
            utility.setCellData("Sheet1", r, 1, population);
            utility.setCellData("Sheet1", r, 2, world);
            utility.setCellData("Sheet1", r, 3, date);
            utility.setCellData("Sheet1", r, 4, source);
        }
        System.out.println("Web scraping is done successfully...");
        driver.close();
    }
}

测试结果

生成population.xlsx

在Excel中单元格内容为日期格式

java 复制代码
package com.apache.poi.demo;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

public class WorkingWithDateCells {
    public static void main(String[] args) throws IOException {

        // 创建一个空的工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 创建一个工作表格
        XSSFSheet sheet = workbook.createSheet("Date formats");
        sheet.setColumnWidth(0, 256 * 20);

        XSSFCell cell = sheet.createRow(0).createCell(0);

        cell.setCellValue(new Date());


        CreationHelper creationHelper = workbook.getCreationHelper();

        // 格式化  yyyy-MM-dd HH:mm:ss
        CellStyle style = workbook.createCellStyle();
        style.setDataFormat(creationHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));
        cell.setCellStyle(style);


        FileOutputStream fos = new FileOutputStream(".\\datafiles\\dataformats.xlsx", true);

        workbook.write(fos);

        fos.close();
        workbook.close();
    }
}

测试结果

代码地址

https://gitee.com/BAIXUEQIAN/java-study/tree/develop/Apache-Poi-Demo

相关推荐
学习编程的Kitty21 分钟前
算法——位运算
java·前端·算法
用户9047066835739 分钟前
如何使用 Spring MVC 实现 RESTful API 接口
java·后端
刘某某.40 分钟前
数组和小于等于k的最长子数组长度b
java·数据结构·算法
程序员飞哥1 小时前
真正使用的超时关单策略是什么?
java·后端·面试
用户904706683571 小时前
SpringBoot 多环境配置与启动 banner 修改
java·后端
小old弟1 小时前
后端三层架构
java·后端
花花鱼1 小时前
spring boot 2.x 与 spring boot 3.x 及对应Tomcat、Jetty、Undertow版本的选择(理论)
java·后端
温柔一只鬼.1 小时前
Docker快速入门——第二章Docker基本概念
java·docker·容器
要争气1 小时前
5 二分查找算法应用
java·数据结构·算法
郑..方..醒1 小时前
java实现ofd转pdf
java·pdf