多个sheet Excel 数据 导入数据库 如何实现?

Posted libin9iOak

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多个sheet Excel 数据 导入数据库 如何实现?相关的知识,希望对你有一定的参考价值。

文章目录

多个sheet Excel 数据 导入数据库 如何实现?

将 Excel 文件中的多个 sheet 导入数据库,一般有以下几种实现方式:

  1. 使用 JDBC 直接插入。可以使用 Java 的 JDBC 接口直接连接数据库,然后读取 Excel 文件中的数据,并将数据插入到数据库中。这种方式比较直接,但需要编写大量的 JDBC 代码,对 Excel 文件格式的支持也比较有限。

  2. 使用第三方库。市面上有很多 Java 的第三方库可以用来读取 Excel 文件,如 Apache POI、JExcelAPI、EasyExcel 等。这些库通常都提供了比较简单易用的 API,可以方便地读取 Excel 文件中的数据,并将数据插入到数据库中。

  3. 先将 Excel 文件转换成 CSV 文件,再导入数据库。Excel 文件可以先转换成 CSV 文件,然后使用 JDBC 直接将数据插入到数据库中。CSV 文件相对于 Excel 文件来说,结构更加简单,处理起来也更加方便。

无论使用哪种方式,都需要注意以下几个问题:

Excel 文件格式的兼容性问题。不同版本的 Excel 文件可能存在格式差异,需要进行测试和兼容性处理。

数据的类型和格式问题。Excel 文件中的数据类型和格式可能需要进行转换和处理,以适配数据库中的数据类型和格式要求。

数据的一致性问题。如果 Excel 文件中的数据有重复或冲突,需要进行处理,以保证数据的一致性和完整性。

综上所述,将 Excel 文件中的多个 sheet 导入数据库的实现方式有多种,具体使用哪种方式,还需要根据实际情况进行评估和选择。

传统方式

处理 普通数据的 Excel 文件,需要考虑到内存和性能的问题,以下是一个基于流式读取和写入的示例代码:

// 获取 Excel 文件输入流
InputStream is = new BufferedInputStream(new FileInputStream(filePath));
Workbook workbook = WorkbookFactory.create(is);

// 遍历每个 Sheet
for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) 
    Sheet sheet = workbook.getSheetAt(sheetIndex);
    String sheetName = sheet.getSheetName();
    System.out.println("开始处理 Sheet:" + sheetName);

    // 准备写入的输出流
    OutputStream os = new BufferedOutputStream(new FileOutputStream(outputDir + "/" + sheetName + ".xlsx"));

    // 设置写入的 Sheet 名称
    SXSSFWorkbook writer = new SXSSFWorkbook(new XSSFWorkbook(), 10000);
    SXSSFSheet outSheet = writer.createSheet(sheetName);

    // 读取并写入 Sheet 的标题行
    Row titleRow = sheet.getRow(0);
    Row outTitleRow = outSheet.createRow(0);
    for (int i = 0; i < titleRow.getLastCellNum(); i++) 
        outTitleRow.createCell(i).setCellValue(titleRow.getCell(i).getStringCellValue());
    

    // 逐行读取并写入数据
    for (int i = 1; i <= sheet.getLastRowNum(); i++) 
        Row row = sheet.getRow(i);
        Row outRow = outSheet.createRow(i);
        for (int j = 0; j < row.getLastCellNum(); j++) 
            Cell cell = row.getCell(j);
            if (cell != null) 
                switch (cell.getCellType()) 
                    case BLANK:
                        outRow.createCell(j, CellType.BLANK);
                        break;
                    case BOOLEAN:
                        outRow.createCell(j, CellType.BOOLEAN).setCellValue(cell.getBooleanCellValue());
                        break;
                    case ERROR:
                        outRow.createCell(j, CellType.ERROR).setCellValue(cell.getErrorCellValue());
                        break;
                    case FORMULA:
                        outRow.createCell(j, CellType.FORMULA).setCellFormula(cell.getCellFormula());
                        break;
                    case NUMERIC:
                        if (DateUtil.isCellDateFormatted(cell)) 
                            outRow.createCell(j, CellType.NUMERIC).setCellValue(cell.getDateCellValue());
                         else 
                            outRow.createCell(j, CellType.NUMERIC).setCellValue(cell.getNumericCellValue());
                        
                        break;
                    case STRING:
                        outRow.createCell(j, CellType.STRING).setCellValue(cell.getStringCellValue());
                        break;
                    default:
                        outRow.createCell(j, CellType.BLANK);
                        break;
                
            
        

        // 每隔 10000 行进行一次缓存写入
        if (i % 10000 == 0) 
            ((SXSSFSheet) outSheet).flushRows();
        
    

    // 最后写入缓存的数据
    writer.write(os);
    os.flush();
    os.close();
    writer.dispose();
    System.out.println("处理 Sheet:" + sheetName + " 完成");


// 关闭输入流
is.close();



上述示例代码使用了 Apache POI 的流式读取和写入方式,可以有效地处理大量数据。为了避免内存溢出,采用了缓存写入的方式,每隔一定数量的行进行一次写入操作。

Apache POI

使用 Apache POI 实现将 Excel 文件中的多个 sheet 导入到数据库的 Java 代码:

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelImporter 
    private static final String DB_URL = "jdbc:mysql://localhost:3306/mydatabase";
    private static final String DB_USER = "myuser";
    private static final String DB_PASSWORD = "mypassword";
    private static final String INSERT_SQL = "INSERT INTO mytable (col1, col2, col3) VALUES (?, ?, ?)";

    public static void main(String[] args) 
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) 
            FileInputStream file = new FileInputStream("myexcel.xlsx");
            Workbook workbook = new XSSFWorkbook(file);
            int numSheets = workbook.getNumberOfSheets();

            for (int i = 0; i < numSheets; i++) 
                Sheet sheet = workbook.getSheetAt(i);
                for (Row row : sheet) 
                    String col1 = null;
                    String col2 = null;
                    int col3 = 0;

                    for (Cell cell : row) 
                        int columnIndex = cell.getColumnIndex();
                        switch (columnIndex) 
                            case 0:
                                col1 = cell.getStringCellValue();
                                break;
                            case 1:
                                col2 = cell.getStringCellValue();
                                break;
                            case 2:
                                col3 = (int) cell.getNumericCellValue();
                                break;
                            default:
                                // Ignore other columns
                                break;
                        
                    

                    PreparedStatement statement = conn.prepareStatement(INSERT_SQL);
                    statement.setString(1, col1);
                    statement.setString(2, col2);
                    statement.setInt(3, col3);
                    statement.executeUpdate();
                
            

            System.out.println("Import successful");
         catch (SQLException e) 
            e.printStackTrace();
         catch (Exception e) 
            e.printStackTrace();
        
    


在上面的代码中,首先通过 FileInputStream 和 Workbook 对象读取 Excel 文件中的数据,然后通过 for 循环遍历每个 sheet 和每行数据,并将数据插入到数据库中。在读取单元格数据时,可以根据单元格的列索引和数据类型进行类型转换和赋值。最后通过 PreparedStatement 执行 SQL 插入语句,将数据插入到数据库中。

需要注意的是,上面的代码只是一个简单的示例,还需要根据实际情况进行修改和完善,比如加入异常处理、事务管理等功能。

JExcelAPI

使用 JExcelAPI 实现将 Excel 文件中的多个 sheet 导入到数据库的 Java 代码:

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;

public class ExcelImporter 
    private static final String DB_URL = "jdbc:mysql://localhost:3306/mydatabase";
    private static final String DB_USER = "myuser";
    private static final String DB_PASSWORD = "mypassword";
    private static final String INSERT_SQL = "INSERT INTO mytable (col1, col2, col3) VALUES (?, ?, ?)";

    public static void main(String[] args) 
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) 
            Workbook workbook = Workbook.getWorkbook(new File("myexcel.xls"));
            int numSheets = workbook.getNumberOfSheets();

            for (int i = 0; i < numSheets; i++) 
                Sheet sheet = workbook.getSheet(i);
                for (int j = 1; j < sheet.getRows(); j++) 
                    String col1 = null;
                    String col2 = null;
                    int col3 = 0;

                    for (int k = 0; k < sheet.getColumns(); k++) 
                        Cell cell = sheet.getCell(k, j);
                        switch (k) 
                            case 0:
                                col1 = cell.getContents();
                                break;
                            case 1:
                                col2 = cell.getContents();
                                break;
                            case 2:
                                col3 = Integer.parseInt(cell.getContents());
                                break;
                            default:
                                // Ignore other columns
                                break;
                        
                    

                    PreparedStatement statement = conn.prepareStatement(INSERT_SQL);
                    statement.setString(1, col1);
                    statement.setString(2, col2);
                    statement.setInt(3, col3);
                    statement.executeUpdate();
                
            

            System.out.println("Import successful");
         catch (SQLException e) 
            e.printStackTrace();
         catch (Exception e) 
            e.printStackTrace();
        
    



在上面的代码中,首先通过 Workbook 对象读取 Excel 文件中的数据,然后通过 for 循环遍历每个 sheet 和每行数据,并将数据插入到数据库中。在读取单元格数据时,可以根据单元格的行索引、列索引和数据类型进行类型转换和赋值。最后通过 PreparedStatement 执行 SQL 插入语句,将数据插入到数据库中。

需要注意的是,上面的代码只是一个简单的示例,还需要根据实际情况进行修改和完善,比如加入异常处理、事务管理等功能。另外,JExcelAPI 只支持旧版的 .xls 格式,不支持 .xlsx 格式

EasyExcel

使用 EasyExcel 实现将 Excel 文件中的多个 sheet 导入到数据库的 Java 代码:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.Sheet;

import java.util.ArrayList;
import java.util.List;

public class ExcelImporter 
    private static final String DB_URL = "jdbc:mysql://localhost:3306/mydatabase";
    private static final String DB_USER = "myuser";
    private static final String DB_PASSWORD = "mypassword";
    private static final String INSERT_SQL = "INSERT INTO mytable (col1, col2, col3) VALUES (?, ?, ?)";

    public static void main(String[] args) 
        List<List<Object>> data = new ArrayList<>();
        EasyExcel.read("myexcel.xlsx", new MyEventListener()).sheet().doRead();
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) 
            PreparedStatement statement = conn.prepareStatement(INSERT_SQL);

            for (List<Object> row : data) 
                statement.setString(1, (String) row.get(0));
                statement.setString(2, (String) row.get(1));
                statement.setInt(3, (Integer) row.get(2));
                statement.addBatch();
            

            statement.executeBatch();
            System.out.println("Import successful");
         catch (SQLException e) 
            e.printStackTrace();
         catch (Exception e) 
            e.printStackTrace();
        
    

    static class MyEventListener extends AnalysisEventListener<Object> 
        private List<Object> row = new ArrayList<>();

        @Override
        public void invoke(Object data, AnalysisContext context) 
            row.add(data);
            if (context.getCurrentRowNum() == 0) 
                // Ignore the header row
                row.clear();
            
        

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) 
            // Ignore
        

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) 
            // Ignore
        
    


在上面的代码中,首先通过 EasyExcel 对象读取 Excel 文件中的数据,然后通过 AnalysisEventListener 监听器将每行数据存储到一个 List 中,最后将 List 中的数据插入到数据库中。需要注意的是,在处理每行数据时,需要根据数据类型进行类型转换和赋值。此外,EasyExcel 支持 .xlsx 和 .xls 格式的 Excel 文件,但由于 .xlsx 格式的文件在读取时需要占用大量内存,因此建议在处理大量数据时使用 .xls 格式。

需要注意的是,上面的代码只是一个简单的示例,还需要根据实际情况进行修改和完善,比如加入异常处理、事务管理等功能。另外,EasyExcel 还提供了很多高级功能,比如读取大量数据时的分页读取、读取时的数据转换和验证等。可以根据实际需求进行使用。

总结

除了使用 Apache POI 和 EasyExcel 这两个库之外,还有其他的实现方式,比如:

使用 OpenCSV:OpenCSV 是一个轻量级的 CSV 格式文件读写库,也支持读写 Excel 文件。与 Apache POI 相比,它的内存占用更少,但功能相对较少。

使用 JExcelAPI:JExcelAPI 是一个老牌的 Java Excel 文件读写库,也支持读写多个 sheet。与 Apache POI 相比,它的内存占用更少,但功能相对较少。

使用 Excel Streaming Reader:Excel Streaming Reader 是一个基于 SAX 的 Excel 文件读取库,能够高效地读取大型 Excel 文件。与 Apache POI 相比,它的内存占用更少,但功能相对较少。

使用 CSV 文件代替 Excel 文件:如果数据量不是很大,并且不需要使用 Excel 特有的功能,可以将 Excel 文件转换为 CSV 格式文件,然后使用 OpenCSV 或其他的 CSV 文件读写库进行读写。

需要根据实际情况选择合适的实现方式,综合考虑内存占用、性能、功能等因素。

结语

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、评论、收藏➕关注,您的支持是我坚持写作最大的动力。

2007版本excel多个sheet页数据通过ibatis批量导入数据库

页面部分

<form method="post" name ="test" enctype="multipart/form-data">

<input type="file" name="file"/>

</form>

实体类部分

public Class Test{

   private String id;

   private String name;

   private String address;

 //以下为get、set方法(省略)

}

Action部分

按照strusts2获取file

private File file;
 private String fileName;
 private String fileContentType;

添加get、set方法

//获取workBook对象

XSSFWorkbook workBook = new XSSFWorkbook(file.getInputStream());

//定义workSheet

XSSFSheet workSheet = null;

//定义从excel获取的数据拼接成一个List对象

List<Test> listTest=new ArrayList<Test>();

//获取sheet页数量

int sheetCount = workBook.getNumberOfSheets();

for(int i=0;i<sheetCount;i++){

//获取第i个sheet

 workSheet = workBook.getSheetAt(i);

//获取该sheet页的行数

  for(int j=0;j<workSheet.getPhysicalNumberOfRows(); j++){

       //获取第j行

        XSSFRow row = workSheet.getRow(j);

       Test test=new Test();

        //row.getCell(0)获取第j行第1个单元格的数据

        test.setId(row.getCell(0)==null ? "":row.getCell(0).toString().trim());

//判断 如果第2行为数字格式   转成字符串

        if(row.getCell(1) !=null && row.getCell(1).getCellType() == XSSFCell.CELL_TYPE_NUMERIC){
      row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
     }

   test.setName(row.getCell(1)==null ? "":row.getCell(1).toString().trim());

  test.setAddress(row.getCell(2)==null ? "":row.getCell(2).toString().trim());

listTest.add(test);

}

}

ibatis部分

<insert id="export" parameterClass="java.util.List">

<![CDATA[

insert all

]]>

<iterate conjunction=" ">

<![CDATA[

into test(id,name,address)

values

(#listTest[].id#,#listTest[].name#,#listTest[].address#)

]]>

</iterate>

<![CDATA[

select 1 from dual

]]>

</insert>

 

以上是关于多个sheet Excel 数据 导入数据库 如何实现?的主要内容,如果未能解决你的问题,请参考以下文章

C# winform中如何通过新建EXCEL工作簿把SQL SERVER数据库中多张表导入EXCEL不同的sheet当中啊

2007版本excel多个sheet页数据通过ibatis批量导入数据库

PHP laravel框架 导入导出excel ,phpexcel数据导出分多个工作区(sheet)

利用kettle,怎样把数据导入到同一个excel,不同sheet中

java jxls导入excel 的多个sheet 代码该如何写 配置文件怎么写? 还有jxls 能读入07 excel吗?

poi实现excel数据导入到mysql数据库(加上excel的验证)