多个sheet Excel 数据 导入数据库 如何实现?
Posted libin9iOak
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多个sheet Excel 数据 导入数据库 如何实现?相关的知识,希望对你有一定的参考价值。
文章目录
多个sheet Excel 数据 导入数据库 如何实现?
将 Excel 文件中的多个 sheet 导入数据库,一般有以下几种实现方式:
-
使用 JDBC 直接插入。可以使用 Java 的 JDBC 接口直接连接数据库,然后读取 Excel 文件中的数据,并将数据插入到数据库中。这种方式比较直接,但需要编写大量的 JDBC 代码,对 Excel 文件格式的支持也比较有限。
-
使用第三方库。市面上有很多 Java 的第三方库可以用来读取 Excel 文件,如 Apache POI、JExcelAPI、EasyExcel 等。这些库通常都提供了比较简单易用的 API,可以方便地读取 Excel 文件中的数据,并将数据插入到数据库中。
-
先将 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吗?