excel2007文件格式与之前版本不同,之前版本采用的是微软自己的存储格式。07版内容的存储采用XML格式,所以,理所当然的,对大数据量的 xlsx文件的读取采用的也是XML的处理方式SAX。
同之前的版本一样,大数据量文件的读取采用的是事件模型eventusermodel。usermodel模式需要将文件一次性全部读到内存中,07版的既然采用的存储模式是xml,解析用的DOM方式也是如此,这种模式操作简单,容易上手,但是对于大量数据占用的内存也是相当可观,在Eclipse中经常出现内存溢出。
下面就是采用eventusermodel对07excel文件读取。
同上篇,我将当前行的单元格数据存储到List中,抽象出 optRows 方法,该方法会在每行末尾时调用,方法参数为当前行索引curRow(int型)及存有行内单元格数据的List。继承类只需实现该行级方法即可。
经测试,对12万条数据,7M大小的文件也能正常运行。无需设置vm的内存空间。
excel读取采用的API为POI3.6,使用前先下载此包,若运行中出现其他依赖包不存在,请下载相应依赖包。
抽象类:XxlsAbstract ,作用:遍历excel文件,提供行级操作方法 optRows
- package com.gaosheng.util.xls;
- import java.io.InputStream;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import org.apache.poi.xssf.eventusermodel.XSSFReader;
- import org.apache.poi.xssf.model.SharedStringsTable;
- import org.apache.poi.xssf.usermodel.XSSFRichTextString;
- import org.apache.poi.openxml4j.opc.OPCPackage;
- import org.xml.sax.Attributes;
- import org.xml.sax.InputSource;
- import org.xml.sax.SAXException;
- import org.xml.sax.XMLReader;
- import org.xml.sax.helpers.DefaultHandler;
- import org.xml.sax.helpers.XMLReaderFactory;
- /**
- * XSSF and SAX (Event API)
- */
- public abstract class XxlsAbstract extends DefaultHandler {
- private SharedStringsTable sst;
- private String lastContents;
- private boolean nextIsString;
- private int sheetIndex = -1;
- private List<String> rowlist = new ArrayList<String>();
- private int curRow = 0;
- private int curCol = 0;
- //excel记录行操作方法,以行索引和行元素列表为参数,对一行元素进行操作,元素为String类型
- // public abstract void optRows(int curRow, List<String> rowlist) throws SQLException ;
- //excel记录行操作方法,以sheet索引,行索引和行元素列表为参数,对sheet的一行元素进行操作,元素为String类型
- public abstract void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException;
- //只遍历一个sheet,其中sheetId为要遍历的sheet索引,从1开始,1-3
- public void processOneSheet(String filename,int sheetId) throws Exception {
- OPCPackage pkg = OPCPackage.open(filename);
- XSSFReader r = new XSSFReader(pkg);
- SharedStringsTable sst = r.getSharedStringsTable();
- XMLReader parser = fetchSheetParser(sst);
- // rId2 found by processing the Workbook
- // 根据 rId# 或 rSheet# 查找sheet
- InputStream sheet2 = r.getSheet("rId"+sheetId);
- sheetIndex++;
- InputSource sheetSource = new InputSource(sheet2);
- parser.parse(sheetSource);
- sheet2.close();
- }
- /**
- * 遍历 excel 文件
- */
- public void process(String filename) throws Exception {
- OPCPackage pkg = OPCPackage.open(filename);
- XSSFReader r = new XSSFReader(pkg);
- SharedStringsTable sst = r.getSharedStringsTable();
- XMLReader parser = fetchSheetParser(sst);
- Iterator<InputStream> sheets = r.getSheetsData();
- while (sheets.hasNext()) {
- curRow = 0;
- sheetIndex++;
- InputStream sheet = sheets.next();
- InputSource sheetSource = new InputSource(sheet);
- parser.parse(sheetSource);
- sheet.close();
- }
- }
- public XMLReader fetchSheetParser(SharedStringsTable sst)
- throws SAXException {
- XMLReader parser = XMLReaderFactory
- .createXMLReader("org.apache.xerces.parsers.SAXParser");
- this.sst = sst;
- parser.setContentHandler(this);
- return parser;
- }
- public void startElement(String uri, String localName, String name,
- Attributes attributes) throws SAXException {
- // c => 单元格
- if (name.equals("c")) {
- // 如果下一个元素是 SST 的索引,则将nextIsString标记为true
- String cellType = attributes.getValue("t");
- if (cellType != null && cellType.equals("s")) {
- nextIsString = true;
- } else {
- nextIsString = false;
- }
- }
- // 置空
- lastContents = "";
- }
- public void endElement(String uri, String localName, String name)
- throws SAXException {
- // 根据SST的索引值的到单元格的真正要存储的字符串
- // 这时characters()方法可能会被调用多次
- if (nextIsString) {
- try {
- int idx = Integer.parseInt(lastContents);
- lastContents = new XSSFRichTextString(sst.getEntryAt(idx))
- .toString();
- } catch (Exception e) {
- }
- }
- // v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
- // 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
- if (name.equals("v")) {
- String value = lastContents.trim();
- value = value.equals("")?" ":value;
- rowlist.add(curCol, value);
- curCol++;
- }else {
- //如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
- if (name.equals("row")) {
- try {
- optRows(sheetIndex,curRow,rowlist);
- } catch (SQLException e) {
- e.printStackTrace();
- }
- rowlist.clear();
- curRow++;
- curCol = 0;
- }
- }
- }
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- //得到单元格内容的值
- lastContents += new String(ch, start, length);
- }
- }
- package com.gaosheng.util.xls;
- import java.io.InputStream;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import org.apache.poi.xssf.eventusermodel.XSSFReader;
- import org.apache.poi.xssf.model.SharedStringsTable;
- import org.apache.poi.xssf.usermodel.XSSFRichTextString;
- import org.apache.poi.openxml4j.opc.OPCPackage;
- import org.xml.sax.Attributes;
- import org.xml.sax.InputSource;
- import org.xml.sax.SAXException;
- import org.xml.sax.XMLReader;
- import org.xml.sax.helpers.DefaultHandler;
- import org.xml.sax.helpers.XMLReaderFactory;
- /**
- * XSSF and SAX (Event API)
- */
- public abstract class XxlsAbstract extends DefaultHandler {
- private SharedStringsTable sst;
- private String lastContents;
- private boolean nextIsString;
- private int sheetIndex = -1;
- private List<String> rowlist = new ArrayList<String>();
- private int curRow = 0;
- private int curCol = 0;
- //excel记录行操作方法,以行索引和行元素列表为参数,对一行元素进行操作,元素为String类型
- // public abstract void optRows(int curRow, List<String> rowlist) throws SQLException ;
- //excel记录行操作方法,以sheet索引,行索引和行元素列表为参数,对sheet的一行元素进行操作,元素为String类型
- public abstract void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException;
- //只遍历一个sheet,其中sheetId为要遍历的sheet索引,从1开始,1-3
- public void processOneSheet(String filename,int sheetId) throws Exception {
- OPCPackage pkg = OPCPackage.open(filename);
- XSSFReader r = new XSSFReader(pkg);
- SharedStringsTable sst = r.getSharedStringsTable();
- XMLReader parser = fetchSheetParser(sst);
- // rId2 found by processing the Workbook
- // 根据 rId# 或 rSheet# 查找sheet
- InputStream sheet2 = r.getSheet("rId"+sheetId);
- sheetIndex++;
- InputSource sheetSource = new InputSource(sheet2);
- parser.parse(sheetSource);
- sheet2.close();
- }
- /**
- * 遍历 excel 文件
- */
- public void process(String filename) throws Exception {
- OPCPackage pkg = OPCPackage.open(filename);
- XSSFReader r = new XSSFReader(pkg);
- SharedStringsTable sst = r.getSharedStringsTable();
- XMLReader parser = fetchSheetParser(sst);
- Iterator<InputStream> sheets = r.getSheetsData();
- while (sheets.hasNext()) {
- curRow = 0;
- sheetIndex++;
- InputStream sheet = sheets.next();
- InputSource sheetSource = new InputSource(sheet);
- parser.parse(sheetSource);
- sheet.close();
- }
- }
- public XMLReader fetchSheetParser(SharedStringsTable sst)
- throws SAXException {
- XMLReader parser = XMLReaderFactory
- .createXMLReader("org.apache.xerces.parsers.SAXParser");
- this.sst = sst;
- parser.setContentHandler(this);
- return parser;
- }
- public void startElement(String uri, String localName, String name,
- Attributes attributes) throws SAXException {
- // c => 单元格
- if (name.equals("c")) {
- // 如果下一个元素是 SST 的索引,则将nextIsString标记为true
- String cellType = attributes.getValue("t");
- if (cellType != null && cellType.equals("s")) {
- nextIsString = true;
- } else {
- nextIsString = false;
- }
- }
- // 置空
- lastContents = "";
- }
- public void endElement(String uri, String localName, String name)
- throws SAXException {
- // 根据SST的索引值的到单元格的真正要存储的字符串
- // 这时characters()方法可能会被调用多次
- if (nextIsString) {
- try {
- int idx = Integer.parseInt(lastContents);
- lastContents = new XSSFRichTextString(sst.getEntryAt(idx))
- .toString();
- } catch (Exception e) {
- }
- }
- // v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
- // 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
- if (name.equals("v")) {
- String value = lastContents.trim();
- value = value.equals("")?" ":value;
- rowlist.add(curCol, value);
- curCol++;
- }else {
- //如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
- if (name.equals("row")) {
- try {
- optRows(sheetIndex,curRow,rowlist);
- } catch (SQLException e) {
- e.printStackTrace();
- }
- rowlist.clear();
- curRow++;
- curCol = 0;
- }
- }
- }
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- //得到单元格内容的值
- lastContents += new String(ch, start, length);
- }
- }
继承类:XxlsBig,作用:将数据转出到数据库临时表
- package com.gaosheng.util.examples.xls;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.List;
- import java.util.Properties;
- import com.gaosheng.util.xls.XxlsAbstract;
- public class XxlsBig extends XxlsAbstract {
- public static void main(String[] args) throws Exception {
- XxlsBig howto = new XxlsBig("temp_table");
- howto.processOneSheet("F:/new.xlsx",1);
- howto.process("F:/new.xlsx");
- howto.close();
- }
- public XxlsBig(String tableName) throws SQLException{
- this.conn = getNew_Conn();
- this.statement = conn.createStatement();
- this.tableName = tableName;
- }
- private Connection conn = null;
- private Statement statement = null;
- private PreparedStatement newStatement = null;
- private String tableName = "temp_table";
- private boolean create = true;
- public void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException {
- if (sheetIndex == 0 && curRow == 0) {
- StringBuffer preSql = new StringBuffer("insert into " + tableName
- + " values(");
- StringBuffer table = new StringBuffer("create table " + tableName
- + "(");
- int c = rowlist.size();
- for (int i = 0; i < c; i++) {
- preSql.append("?,");
- table.append(rowlist.get(i));
- table.append(" varchar2(100) ,");
- }
- table.deleteCharAt(table.length() - 1);
- preSql.deleteCharAt(preSql.length() - 1);
- table.append(")");
- preSql.append(")");
- if (create) {
- statement = conn.createStatement();
- try{
- statement.execute("drop table "+tableName);
- }catch(Exception e){
- }finally{
- System.out.println("表 "+tableName+" 删除成功");
- }
- if (!statement.execute(table.toString())) {
- System.out.println("创建表 "+tableName+" 成功");
- // return;
- } else {
- System.out.println("创建表 "+tableName+" 失败");
- return;
- }
- }
- conn.setAutoCommit(false);
- newStatement = conn.prepareStatement(preSql.toString());
- } else if(curRow>0) {
- // 一般行
- int col = rowlist.size();
- for (int i = 0; i < col; i++) {
- newStatement.setString(i + 1, rowlist.get(i).toString());
- }
- newStatement.addBatch();
- if (curRow % 1000 == 0) {
- newStatement.executeBatch();
- conn.commit();
- }
- }
- }
- private static Connection getNew_Conn() {
- Connection conn = null;
- Properties props = new Properties();
- FileInputStream fis = null;
- try {
- fis = new FileInputStream("D:/database.properties");
- props.load(fis);
- DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
- // String jdbcURLString =
- // "jdbc:oracle:thin:@192.168.0.28:1521:orcl";
- StringBuffer jdbcURLString = new StringBuffer();
- jdbcURLString.append("jdbc:oracle:thin:@");
- jdbcURLString.append(props.getProperty("host"));
- jdbcURLString.append(":");
- jdbcURLString.append(props.getProperty("port"));
- jdbcURLString.append(":");
- jdbcURLString.append(props.getProperty("database"));
- conn = DriverManager.getConnection(jdbcURLString.toString(), props
- .getProperty("user"), props.getProperty("password"));
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- fis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return conn;
- }
- public int close() {
- try {
- newStatement.executeBatch();
- conn.commit();
- System.out.println("数据写入完毕");
- this.newStatement.close();
- this.statement.close();
- this.conn.close();
- return 1;
- } catch (SQLException e) {
- return 0;
- }
- }
- }
- package com.gaosheng.util.examples.xls;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.List;
- import java.util.Properties;
- import com.gaosheng.util.xls.XxlsAbstract;
- public class XxlsBig extends XxlsAbstract {
- public static void main(String[] args) throws Exception {
- XxlsBig howto = new XxlsBig("temp_table");
- howto.processOneSheet("F:/new.xlsx",1);
- howto.process("F:/new.xlsx");
- howto.close();
- }
- public XxlsBig(String tableName) throws SQLException{
- this.conn = getNew_Conn();
- this.statement = conn.createStatement();
- this.tableName = tableName;
- }
- private Connection conn = null;
- private Statement statement = null;
- private PreparedStatement newStatement = null;
- private String tableName = "temp_table";
- private boolean create = true;
- public void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException {
- if (sheetIndex == 0 && curRow == 0) {
- StringBuffer preSql = new StringBuffer("insert into " + tableName
- + " values(");
- StringBuffer table = new StringBuffer("create table " + tableName
- + "(");
- int c = rowlist.size();
- for (int i = 0; i < c; i++) {
- preSql.append("?,");
- table.append(rowlist.get(i));
- table.append(" varchar2(100) ,");
- }
- table.deleteCharAt(table.length() - 1);
- preSql.deleteCharAt(preSql.length() - 1);
- table.append(")");
- preSql.append(")");
- if (create) {
- statement = conn.createStatement();
- try{
- statement.execute("drop table "+tableName);
- }catch(Exception e){
- }finally{
- System.out.println("表 "+tableName+" 删除成功");
- }
- if (!statement.execute(table.toString())) {
- System.out.println("创建表 "+tableName+" 成功");
- // return;
- } else {
- System.out.println("创建表 "+tableName+" 失败");
- return;
- }
- }
- conn.setAutoCommit(false);
- newStatement = conn.prepareStatement(preSql.toString());
- } else if(curRow>0) {
- // 一般行
- int col = rowlist.size();
- for (int i = 0; i < col; i++) {
- newStatement.setString(i + 1, rowlist.get(i).toString());
- }
- newStatement.addBatch();
- if (curRow % 1000 == 0) {
- newStatement.executeBatch();
- conn.commit();
- }
- }
- }
- private static Connection getNew_Conn() {
- Connection conn = null;
- Properties props = new Properties();
- FileInputStream fis = null;
- try {
- fis = new FileInputStream("D:/database.properties");
- props.load(fis);
- DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
- // String jdbcURLString =
- // "jdbc:oracle:thin:@192.168.0.28:1521:orcl";
- StringBuffer jdbcURLString = new StringBuffer();
- jdbcURLString.append("jdbc:oracle:thin:@");
- jdbcURLString.append(props.getProperty("host"));
- jdbcURLString.append(":");
- jdbcURLString.append(props.getProperty("port"));
- jdbcURLString.append(":");
- jdbcURLString.append(props.getProperty("database"));
- conn = DriverManager.getConnection(jdbcURLString.toString(), props
- .getProperty("user"), props.getProperty("password"));
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- fis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return conn;
- }
- public int close() {
- try {
- newStatement.executeBatch();
- conn.commit();
- System.out.println("数据写入完毕");
- this.newStatement.close();
- this.statement.close();
- this.conn.close();
- return 1;
- } catch (SQLException e) {
- return 0;
- }
- }
- }
继承类:XxlsPrint,作用:将数据输出到控制台
- package com.gaosheng.util.examples.xls;
- import java.sql.SQLException;
- import java.util.List;
- import com.gaosheng.util.xls.XxlsAbstract;
- public class XxlsPrint extends XxlsAbstract {
- @Override
- public void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException {
- for (int i = 0; i < rowlist.size(); i++) {
- System.out.print("'" + rowlist.get(i) + "',");
- }
- System.out.println();
- }
- public static void main(String[] args) throws Exception {
- XxlsPrint howto = new XxlsPrint();
- howto.processOneSheet("F:/new.xlsx",1);
- // howto.processAllSheets("F:/new.xlsx");
- }
- }
- package com.gaosheng.util.examples.xls;
- import java.sql.SQLException;
- import java.util.List;
- import com.gaosheng.util.xls.XxlsAbstract;
- public class XxlsPrint extends XxlsAbstract {
- @Override
- public void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException {
- for (int i = 0; i < rowlist.size(); i++) {
- System.out.print("'" + rowlist.get(i) + "',");
- }
- System.out.println();
- }
- public static void main(String[] args) throws Exception {
- XxlsPrint howto = new XxlsPrint();
- howto.processOneSheet("F:/new.xlsx",1);
- // howto.processAllSheets("F:/new.xlsx");
- }
- }
源代码在附件中,还包含了说明文件、数据库配置文件、以及整合xls文件和xlsx文件读取的类:Xls2Do。
相关推荐
在IT行业中,处理大数据量的Excel文件是一项常见的任务,特别是在数据分析、报表生成和数据导入导出等场景。本文主要探讨如何高效地读取2003及之前版本的Excel文件,这些版本通常采用.BIFF(Binary Interchange File...
这个名为"安卓Android源码——安卓读取Excel文件获取表格数据.rar"的压缩包文件,很可能包含了一个示例项目,教你如何在Android应用中实现这一功能。 首先,让我们了解在Android中读取Excel文件的基本步骤。Android...
本项目“安卓Android源码——安卓读取Excel文件获取表格数据”提供了一个示例,展示了如何在Android应用中实现这一功能。下面将详细探讨相关知识点。 1. **Excel文件格式** Excel文件通常以`.xls`或`.xlsx`为扩展...
OpenXLSX是一个轻量级且高效的开源库,它允许开发者在C++环境中方便地读取、写入、创建和修改.xlsx格式的Excel文件。这个库以其简洁的API和对现代C++标准的良好支持,为开发者提供了强大的功能。 OpenXLSX库的核心...
此外,考虑到性能和内存消耗,可能需要对大数据量的Excel文件进行分页处理,而不是一次性加载所有数据。 这个压缩包中的“cf_shuangSeQiu”文件可能是源码的一部分,但具体细节无法在此处分析,因为它不是一个明确...
在Android平台上,读取Excel文件是一项常见的需求,例如在数据导入、数据分析或报表展示等场景。本项目将探讨如何在Android Studio开发环境中实现这一功能。首先,我们需要了解Android对文件操作的基本方法,以及...
总的来说,C#中导入Excel读取图片的方法主要分为使用.NET Interop组件和第三方库如EPPlus。选择哪种方法取决于项目需求,如性能、兼容性、是否依赖Office等因素。对于图片上传,通常还会涉及文件流处理、网络传输等...
以下是一段典型的WinRunner脚本代码示例,用于读取指定的Excel文件中的“name”和“pwd”两列数据: ```plaintext table = "C:\\default.xls"; public function get_field_value(in table, in fieldname) { auto ...
ODBC是一个由Microsoft开发的数据访问接口,它为各种数据库系统提供了一个标准的应用程序编程接口(API),使得开发者可以编写一次代码,就能访问多种数据库,如MySQL、SQL Server、Oracle以及我们的主题——Excel。...
由于大数据量可能导致内存溢出,我们可以分批写入数据,比如每次处理10000行: ```python def batch_insert(connection, df, table_name, chunksize=10000): for chunk in df.iterrows(chunksize=chunksize): ...
流式读取适用于大文件,避免一次性加载整个文件导致内存溢出;内存读取则适合小文件,读取速度快,但占用内存。 6. **数据处理**:读取Excel文件后,开发人员可能会进行各种数据处理,如过滤、排序、统计分析,甚至...
首先,要读取Excel文件,我们需要导入Python的一个第三方库——pandas。Pandas是Python中用于数据分析的核心库,提供了DataFrame对象,它是一个二维表格型数据结构,可以方便地进行数据清洗、转换和分析。 安装...
在这个"ASP.NET源码——Excel导入SQLserver源码.zip"的压缩包中,我们可以推测这是一份示例代码,用于演示如何在ASP.NET环境中读取Excel文件并将其数据导入到SQL Server数据库中。 首先,我们需要了解Excel文件的...
`xlsx.js`是一个强大的库,专门用于处理Excel文件,它能够读取、写入和操作XLSX和XLSM文件格式,这两种都是Microsoft Excel广泛使用的二进制文件格式。通过这个库,开发者可以方便地创建工作表,设置单元格的值,...
2. **支持的格式**:ExcelManger支持两种主要的Excel文件格式——.xls(Excel 2003)和.xlsx(Excel 2007及以上)。.xls格式基于二进制文件格式BIFF(Binary Interchange File Format),而.xlsx则是基于Open XML...
《ExcelUtil便捷读取工具 v3.1.6——高效处理Excel数据的利器》 ExcelUtil便捷读取工具是一款高效且易用的Java库,专为处理Excel数据而设计,适用于各种开发场景,如数据分析、报表生成、数据导入导出等。在v3.1.6...
在"安卓Android源码——android 读取展示office2007.rar"中,包含的三个子文件OliveDOCLibrary.zip、OliveXLSLibrary.zip和OlivePPTLibrary.zip可能提供了读取和展示这些文件的库或示例代码。 1. OliveDOCLibrary....
这些函数不仅能够帮助我们轻松获取Excel文件的基本信息,还能够方便地读取Excel中的数据,进而应用于MATLAB中的数据分析与处理任务。此外,通过合理的代码设计(如关闭不必要的Excel进程),可以进一步提高程序的...