`

大数据量的excel读取poi实际应用

阅读更多

1、HxlsAbstract.java

 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
import org.apache.poi.hssf.eventusermodel.HSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFRequest;
import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.LabelRecord;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.NoteRecord;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.RKRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
 * @项目名:保密
 * @包名:保密
 * @文件名:HxlsAbstract.java
 * @日期:Dec 24, 2010 10:54:52 AM
 * @备注:POI导入excel(大数据量)
 * @作者:apple
 */
public abstract class HxlsAbstract implements HSSFListener {
	private int minColumns;
	private POIFSFileSystem fs;
	private PrintStream output;

	private int lastRowNumber;
	private int lastColumnNumber;

	/** Should we output the formula, or the value it has? */
	private boolean outputFormulaValues = true;

	/** For parsing Formulas */
	private SheetRecordCollectingListener workbookBuildingListener;
	private HSSFWorkbook stubWorkbook;

	// Records we pick up as we process
	private SSTRecord sstRecord;
	private FormatTrackingHSSFListener formatListener;

	/** So we known which sheet we're on */
	private int sheetIndex = -1;
	private BoundSheetRecord[] orderedBSRs;
	@SuppressWarnings("unchecked")
	private ArrayList boundSheetRecords = new ArrayList();

	// For handling formulas with string results
	private int nextRow;
	private int nextColumn;
	private boolean outputNextStringRecord;

	private int curRow;
	private List<String> rowlist;
	@SuppressWarnings( "unused")
	private String sheetName;

	public HxlsAbstract(POIFSFileSystem fs)
			throws SQLException {
		this.fs = fs;
		this.output = System.out;
		this.minColumns = -1;
		this.curRow = 0;
		this.rowlist = new ArrayList<String>();
	}

	public HxlsAbstract(String filename) throws IOException,
			FileNotFoundException, SQLException {
		this(new POIFSFileSystem(new FileInputStream(filename)));
	}
	
	//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;
	
	/**
	 * 遍历 excel 文件
	 */
	public void process() throws IOException {
		MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(
				this);
		formatListener = new FormatTrackingHSSFListener(listener);

		HSSFEventFactory factory = new HSSFEventFactory();
		HSSFRequest request = new HSSFRequest();

		if (outputFormulaValues) {
			request.addListenerForAllRecords(formatListener);
		} else {
			workbookBuildingListener = new SheetRecordCollectingListener(
					formatListener);
			request.addListenerForAllRecords(workbookBuildingListener);
		}

		factory.processWorkbookEvents(request, fs);
	}
	
	/**
	 * HSSFListener 监听方法,处理 Record
	 */
	@SuppressWarnings("unchecked")
	public void processRecord(Record record) {
		int thisRow = -1;
		int thisColumn = -1;
		String thisStr = null;
		String value = null;
		
		switch (record.getSid()) {
		case BoundSheetRecord.sid:
			boundSheetRecords.add(record);
			break;
		case BOFRecord.sid:
			BOFRecord br = (BOFRecord) record;
			if (br.getType() == BOFRecord.TYPE_WORKSHEET) {
				// Create sub workbook if required
				if (workbookBuildingListener != null && stubWorkbook == null) {
					stubWorkbook = workbookBuildingListener
							.getStubHSSFWorkbook();
				}

				// Works by ordering the BSRs by the location of
				// their BOFRecords, and then knowing that we
				// process BOFRecords in byte offset order
				sheetIndex++;
				if (orderedBSRs == null) {
					orderedBSRs = BoundSheetRecord
							.orderByBofPosition(boundSheetRecords);
				}
				sheetName = orderedBSRs[sheetIndex].getSheetname();
			}
			break;

		case SSTRecord.sid:
			sstRecord = (SSTRecord) record;
			break;

		case BlankRecord.sid:
			BlankRecord brec = (BlankRecord) record;

			thisRow = brec.getRow();
			thisColumn = brec.getColumn();
			thisStr = "";
			break;
		case BoolErrRecord.sid:
			BoolErrRecord berec = (BoolErrRecord) record;

			thisRow = berec.getRow();
			thisColumn = berec.getColumn();
			thisStr = "";
			break;

		case FormulaRecord.sid:
			FormulaRecord frec = (FormulaRecord) record;

			thisRow = frec.getRow();
			thisColumn = frec.getColumn();

			if (outputFormulaValues) {
				if (Double.isNaN(frec.getValue())) {
					// Formula result is a string
					// This is stored in the next record
					outputNextStringRecord = true;
					nextRow = frec.getRow();
					nextColumn = frec.getColumn();
				} else {
					thisStr = formatListener.formatNumberDateCell(frec);
				}
			} else {
				thisStr = '"' + HSSFFormulaParser.toFormulaString(stubWorkbook,
						frec.getParsedExpression()) + '"';
			}
			break;
		case StringRecord.sid:
			if (outputNextStringRecord) {
				// String for formula
				StringRecord srec = (StringRecord) record;
				thisStr = srec.getString();
				thisRow = nextRow;
				thisColumn = nextColumn;
				outputNextStringRecord = false;
			}
			break;

		case LabelRecord.sid:
			LabelRecord lrec = (LabelRecord) record;

			curRow = thisRow = lrec.getRow();
			thisColumn = lrec.getColumn();
			value = lrec.getValue().trim();
			value = value.equals("")?" ":value;
			this.rowlist.add(thisColumn, value);
			break;
		case LabelSSTRecord.sid:
			LabelSSTRecord lsrec = (LabelSSTRecord) record;

			curRow = thisRow = lsrec.getRow();
			thisColumn = lsrec.getColumn();
			if (sstRecord == null) {
				rowlist.add(thisColumn, " ");
			} else {
				value =  sstRecord
				.getString(lsrec.getSSTIndex()).toString().trim();
				value = value.equals("")?" ":value;
				rowlist.add(thisColumn,value);
			}
			break;
		case NoteRecord.sid:
			NoteRecord nrec = (NoteRecord) record;

			thisRow = nrec.getRow();
			thisColumn = nrec.getColumn();
			// TODO: Find object to match nrec.getShapeId()
			thisStr = '"' + "(TODO)" + '"';
			break;
		case NumberRecord.sid:
			NumberRecord numrec = (NumberRecord) record;

			curRow = thisRow = numrec.getRow();
			thisColumn = numrec.getColumn();
			value = formatListener.formatNumberDateCell(numrec).trim();
			value = value.equals("")?" ":value;
			// Format
			rowlist.add(thisColumn, value);
			break;
		case RKRecord.sid:
			RKRecord rkrec = (RKRecord) record;

			thisRow = rkrec.getRow();
			thisColumn = rkrec.getColumn();
			thisStr = '"' + "(TODO)" + '"';
			break;
		default:
			break;
		}

		// 遇到新行的操作
		if (thisRow != -1 && thisRow != lastRowNumber) {
			lastColumnNumber = -1;
		}

		// 空值的操作
		if (record instanceof MissingCellDummyRecord) {
			MissingCellDummyRecord mc = (MissingCellDummyRecord) record;
			curRow = thisRow = mc.getRow();
			thisColumn = mc.getColumn();
			rowlist.add(thisColumn," ");
		}

		// 如果遇到能打印的东西,在这里打印
		if (thisStr != null) {
			if (thisColumn > 0) {
				output.print(',');
			}
			output.print(thisStr);
		}

		// 更新行和列的值
		if (thisRow > -1)
			lastRowNumber = thisRow;
		if (thisColumn > -1)
			lastColumnNumber = thisColumn;

		// 行结束时的操作
		if (record instanceof LastCellOfRowDummyRecord) {
			if (minColumns > 0) {
				// 列值重新置空
				if (lastColumnNumber == -1) {
					lastColumnNumber = 0;
				}
			}
			// 行结束时, 调用 optRows() 方法
			lastColumnNumber = -1;
			try {
				optRows(sheetIndex,curRow, rowlist);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rowlist.clear();
		}
	}
}

 

2、SPImportAction.java

 

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import net.hlj.cms.gnet.model.SPModel;
import net.hlj.cms.gnet.service.SPImportService;
import net.hlj.cms.gnet.service.imp.SPImportServiceImpl;
import net.hlj.cms.gnet.util.HxlsAbstract;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
 * @项目名:保密
 * @包名:保密
 * @文件名:SPImportAction.java
 * @日期:Dec 23, 2010 3:54:16 PM
 * @备注:增值业务导入
 * @作者:apple
 */
public class SPImportAction extends HxlsAbstract{

	private static String fileName="增值业务(测试库).xls";//文件名
	private static String path="D:\\net\\";//路径
	private ApplicationContext ctx = new FileSystemXmlApplicationContext("/WebRoot/WEB-INF/applicationContext.xml");//spring 上下文
	private SPImportService server=new SPImportServiceImpl();//接口
	private static int count=0;
	private static int successCount=0;
	private static int failCount=0;
	private static ArrayList errorList=new ArrayList();
	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		SPImportAction excel;//excel对象
		try 
		{
			excel=new SPImportAction(path+fileName);
			excel.process();
			System.out.println("一共:"+count+"条数据");
			System.out.println("成功:"+successCount+"条数据");
			System.out.println("失败:"+failCount+"条数据");
			for(int i=0;i<errorList.size();i++)
			{
				System.out.println("失败行数:"+errorList.get(i));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
  @Override  
  public void optRows(int sheetIndex,int curRow, List<String> rowlist) throws SQLException 
  {   
	  String row="";
	  if(curRow>0)
	  {
		  if( rowlist.size()==8)
		  {
			  for (int i = 0 ;i< rowlist.size();i++){   
				  row+=rowlist.get(i)+",";
		      }
			  SPModel obj=new SPModel();
			  obj.setPRODUCTID(rowlist.get(1));
			  obj.setV_busiCode(rowlist.get(2));
			  obj.setV_busiName(rowlist.get(4));
			  obj.setV_busiDes(rowlist.get(5));
			  obj.setEFFDATE(rowlist.get(6));
			  obj.setEXPDATE(rowlist.get(7));
			  if(rowlist.get(3).equals("4"))
			  {
				  obj.setFlag("1");
			  }
			  else
			  {
				  obj.setFlag("0");
			  }
			  
			  if(server.isSP(obj, ctx))
			  {
				  int uflag=server.SPUpdate(obj, ctx);
				  if(uflag>0)
				  {
					  successCount++;
					  System.out.println("第"+rowlist.get(0)+"行数据修改成功");
				  }
				  else
				  {
					  failCount++;
					  System.out.println("第"+rowlist.get(0)+"行数据修改失败");
					  errorList.add(rowlist.get(0));
				  }
			  }
			  else
			  {
				  int aflag=server.SPAdd(obj, ctx);
				  if(aflag>0)
				  {
					  successCount++;
					  System.out.println("第"+rowlist.get(0)+"行数据新增成功"); 
				  }
				  else
				  {
					  failCount++;
					  System.out.println("第"+rowlist.get(0)+"行数据新增失败");
					  errorList.add(rowlist.get(0));
				  }
			  }
			  count++;
			  System.out.println(row.substring(0,row.length()-1)); 
		  }
	  }
	  
	  
	  
  }   
  public SPImportAction(String filename) throws IOException,FileNotFoundException, SQLException 
  {   
	  super(filename);   
  }   
}

 

分享到:
评论

相关推荐

    使用Poi读取大数据量excel的方法

    在Java开发中,Apache POI库是一个非常实用的工具,用于读取...总之,Apache POI结合SAX API为在Android上处理大数据量Excel文件提供了有效方案,通过合理配置和优化,可以显著降低内存消耗,提高应用的稳定性和效率。

    Java读取大数据量Excel的方法(POI)

    接下来,我们将详细讲解如何使用Apache POI读取大数据量的Excel文件: 1. **创建Workbook对象**:这是处理Excel文件的基础,它代表整个Excel工作簿。你可以通过`XSSFWorkbook`类的构造函数,传入文件的输入流来创建...

    poi读取大数据量excel文件,避免内存溢出,行级操作

    poi读取大数据量excel文件,避免内存溢出,行级操作 根据本网站的资源修改的。 将一些类路径错误全部进行了修正。 另外,需要自己在类路径里,放spring-context.jar和spring-beans.jar包。

    java poi 导入大数据量Excel数据 防止内存溢出处理.zip

    然而,当处理大数据量的Excel文件时,POI可能会导致内存溢出(Out of Memory, OOM),因为默认情况下它会将整个工作簿加载到内存中。为了防止这种问题,我们需要采用优化策略来高效地处理大量数据。 1. **分块读取*...

    poi大量数据读取gc内存溢出解决方案

    poi读取大量数据会造成gc内存溢出的报错,由于垃圾回收机制无法将大量的对象及时的回收,而这些对象又会保存在内存中,会导致内存不够用的情况,这时候我们就需要使用新的方法,读取为cvs即可.此解决方案可支持千万数据的...

    excle大量数据读取

    在Excel处理大量数据时,传统的读取方法可能会面临性能瓶颈,尤其是在数据量达到10万条甚至更多时,常见的操作可能导致内存溢出,严重影响程序的稳定性和效率。为了解决这个问题,我们需要采用优化的策略来读取和...

    poi 自己写的excel sax方式导入大量数据

    SAX(Simple API for XML)解析方式与DOM不同,它不会一次性加载整个文件到内存,而是逐行读取,只处理当前需要的数据,这极大地降低了内存使用,特别适合处理大数据量的Excel文件。 以下是一些关于使用Apache POI...

    ExcelUtil借助反射和POI对Excel读取,省略了以往读取Excel的繁琐步骤

    在传统的Excel读取方法中,开发者需要手动处理每一行、每一列的数据,这往往涉及大量的代码和复杂的过程。而ExcelUtil则通过优化这些步骤,提供了一个更加简洁高效的解决方案。 首先,让我们理解反射在Java中的作用...

    Java解析大数据量Excel,可解析1048576行excel

    在处理大数据量的Excel文件时,Java是一种常用的语言,因为它提供了强大的库,如Apache POI,使得解析大型Excel文件成为可能。Apache POI是Java的一个开源项目,专门用于读写Microsoft Office格式的文件,包括Excel...

    POI读取Excel带格式数据

    同时,要注意处理大数据量时的性能问题,例如使用`SXSSFWorkbook`来实现内存优化。 总之,Apache POI是Java开发人员处理Excel文件的强大工具,通过理解其API结构和工作原理,我们可以方便地读取和处理Excel中的带...

    poi excel 模板读取并导出带公式的excel文档

    - 考虑到性能问题,如果数据量非常大,可能需要采取分批次处理的方式。 - 对于复杂的公式,建议先在Excel中测试其正确性,再应用于模板文件中。 综上所述,通过使用Apache POI库结合Excel模板文件,可以高效地实现...

    poi excel poi excel poi excel

    ### POI Excel知识点详解 ...掌握 POI 的基本用法对于开发人员来说是非常有用的技能,特别是在需要处理大量数据时更是如此。希望本文能够帮助您更好地理解和使用 Apache POI 进行 Excel 文件的操作。

    java poi 读取百万数据OOM优化

    在Java开发中,处理大量数据是一项挑战,特别是当涉及到读取和操作百万级别的Excel数据时。Excel文件通常存储为二进制格式,如`.xls`或`.xlsx`,这些文件可以容纳大量的行和列,但当数据量过大时,可能会引发内存...

    使用POI导出大数据量到EXCEL

    "使用POI导出大数据量到EXCEL"这个主题涉及到如何高效地利用POI处理大量数据并将其导出到Excel文件中。以下是对这个主题的详细讲解。 1. **Apache POI简介** Apache POI 是一个开源项目,它提供了Java API来创建、...

    POI读取Excel大文件.rar

    POI提供了一个名为SXSSF(Streaming Usermodel API)的接口,设计用于处理大量数据。SXSSF使用滑动窗口模型,只保留最近使用的几百行数据在内存中,其余数据存储在磁盘上,从而显著降低内存消耗。 4. **使用SXSSF...

    java读取excel文件POI+jxl

    在实际应用中,使用这些库通常包括以下几个步骤: 1. 引入相应的库(在本例中,需要引入"poi-scratchpad-3.9.jar")。 2. 创建工作簿对象(Workbook)。 3. 创建工作表对象(Sheet)。 4. 在工作表中添加行(Row)和...

    大数据量Excel读取工具.zip

    "大数据量Excel读取工具.zip"提供的"maven_excel_util-master"可能是为了帮助开发者更高效、稳定地处理大量Excel数据而设计的一个工具或示例代码库,通过使用Java编程和特定的处理策略,克服了Excel原生应用在处理...

    android POI 读取excel 精简jar

    在Android上使用这些库进行Excel读取时,开发者需要注意以下几点: 1. **兼容性**: 考虑到Android设备的多样性,需要确保选择的库能兼容广泛的Android版本。 2. **内存管理**: 因为Android设备的内存有限,处理大型...

    poi读取大文件Excel,使用xml格式解析,速度实测50mb文件13s,可指定sheet页内容,带工具类和测试类

    以上就是关于使用Apache POI的XSSFEventUserModel API解析大文件Excel的关键知识点,以及如何指定读取特定sheet页内容的概述。通过这样的方法,即使面对几十MB甚至更大的Excel文件,也能在较短时间内完成高效读取。

    poi读写excel+poi总结

    Apache POI 是一个开源项目,专门用于处理Microsoft Office格式的文件,包括Excel、Word和PowerPoint等。在本文中,我们将深入探讨如何使用POI...实际应用中,开发者可以根据需求扩展这些基础操作,实现更复杂的功能。

Global site tag (gtag.js) - Google Analytics