一、导入pom依赖poiversion4。0。0poiversion!excelpoidependencygroupIdorg。apache。poigroupIdpoiartifactIdversion{poiversion}versiondependencydependencygroupIdorg。apache。poigroupIdpoiooxmlartifactIdversion{poiversion}versiondependencydependencygroupIdorg。apache。poigroupIdpoiscratchpadartifactIdversion{poiversion}versiondependencydependencygroupIdorg。apache。poigroupIdpoiooxmlschemasartifactIdversion{poiversion}versiondependency 二、导入 1、导入工具类importcom。base。infrastructure。exception。ServiceException;importcom。base。infrastructure。utility。MapUtility;importcom。base。infrastructure。utility。ServiceCheckUtility;importcom。base。infrastructure。utility。StringUtility;importcom。base。infrastructure。utility。excel。analysis。ExcelXlsReader;importcom。base。infrastructure。utility。excel。analysis。ExcelXlsxReader;importorg。springframework。web。multipart。MultipartFile;importjava。io。InputStream;importjava。util。ArrayList;importjava。util。HashMap;importjava。util。List;importjava。util。Map;excel2003、2007大数据量解析publicclassBigExcelReaderUtil{excel2003扩展名privatestaticfinalStringXLSLOWERCASExls;privatestaticfinalStringXLSXLOWERCASExlsx;excel2007扩展名privatestaticfinalStringXLSUPPERCASEXLS;privatestaticfinalStringXLSXUPPERCASEXLSX;根据文件路径解析parampathreturnthrowsExceptionpublicstaticMapString,ObjectreadExcelPath(Stringpath,intheaderIncex,intdataIndex)throwsException{解析数据返回mapMapString,ObjectmapnewHashMap();表头内容ListStringheadernewArrayList();数据内容ListListStringdatanewArrayList();MapInteger,ListListStringlistMapnewHashMap();处理excel2003文件if(path。endsWith(XLSLOWERCASE)path。endsWith(XLSUPPERCASE)){ExcelXlsReaderexcelXlsnewExcelXlsReader(){OverridepublicvoidsendHeaderRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){ServiceCheckUtility。errorCheck(sheetIndex1,请删除或清除多余的sheet页,只保留一个正确的sheet页);header。addAll(cellList);}OverridepublicvoidsendDataRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){ListStringtempListnewArrayList();tempList。addAll(cellList);if(listMap。get(sheetIndex)null){ListListStringdatanewArrayList();data。add(tempList);listMap。put(sheetIndex,data);}else{listMap。get(sheetIndex)。add(tempList);}}};excelXls。process(path,headerIncex,dataIndex);}处理excel2007文件elseif(path。endsWith(XLSXLOWERCASE)path。endsWith(XLSXUPPERCASE)){ExcelXlsxReaderexcelXlsxReadernewExcelXlsxReader(){OverridepublicvoidsendHeaderRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){ServiceCheckUtility。errorCheck(sheetIndex1,请删除或清除多余的sheet页,只保留一个正确的sheet页);header。addAll(cellList);}OverridepublicvoidsendDataRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){ListStringtempListnewArrayList();tempList。addAll(cellList);if(listMap。get(sheetIndex)null){ListListStringdatanewArrayList();data。add(tempList);listMap。put(sheetIndex,data);}else{listMap。get(sheetIndex)。add(tempList);}}};excelXlsxReader。process(path,headerIncex,dataIndex);}else{thrownewException(文件格式错误,上传的excel的扩展名只能是xls或xlsx。);}map。put(data,listMap);map。put(head,header);returnmap;}根据MultipartFile文件对象解析paramfilereturnthrowsExceptionpublicstaticMapString,ObjectreadExcelFile(MultipartFilefile,intheaderIncex,intdataIndex)throwsException{文件判空if(filenull){returnnewHashMap();}获取后缀名判断是否为excelStringsuffixfile。getOriginalFilename()。substring(file。getOriginalFilename()。lastIndexOf(。)1);if(isNotExcelPath(suffix)){returnnewHashMap();}解析数据返回mapMapString,ObjectmapnewHashMap();表头内容ListStringheadernewArrayList();数据内容ListListStringdatanewArrayList();InputStreaminputStreamnull;try{inputStreamfile。getInputStream();if(suffix。endsWith(XLSLOWERCASE)suffix。endsWith(XLSUPPERCASE)){处理excel2003文件ExcelXlsReaderexcelXlsnewExcelXlsReader(){OverridepublicvoidsendHeaderRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){ServiceCheckUtility。errorCheck(sheetIndex1,请删除或清除多余的sheet页,只保留一个正确的sheet页);header。addAll(cellList);}OverridepublicvoidsendDataRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){ListStringtempListnewArrayList();tempList。addAll(cellList);data。add(tempList);}};excelXls。process(inputStream,headerIncex,dataIndex);}elseif(suffix。endsWith(XLSXLOWERCASE)suffix。endsWith(XLSXUPPERCASE)){处理excel2007文件ExcelXlsxReaderexcelXlsxnewExcelXlsxReader(){OverridepublicvoidsendHeaderRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){ServiceCheckUtility。errorCheck(sheetIndex1,请删除或清除多余的sheet页,只保留一个正确的sheet页);header。addAll(cellList);}OverridepublicvoidsendDataRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){ListStringtempListnewArrayList();tempList。addAll(cellList);data。add(tempList);}};excelXlsx。process(inputStream,headerIncex,dataIndex);}else{thrownewServiceException(文件格式错误,上传的excel的扩展名只能是xls或xlsx。);}}finally{if(inputStream!null){inputStream。close();}}map。put(data,data);map。put(head,header);returnmap;}excel路劲检查parampathreturnprivatestaticbooleanisNotExcelPath(Stringpath){if(StringUtility。isEmpty(path)){returntrue;}return!path。endsWith(XLSLOWERCASE)!path。endsWith(XLSXLOWERCASE)!path。endsWith(XLSUPPERCASE)!path。endsWith(XLSXUPPERCASE);}} 2、2003版本解析importjava。io。FileInputStream;importjava。io。InputStream;importjava。util。ArrayList;importjava。util。List;importorg。apache。poi。hssf。eventusermodel。EventWorkbookBuilder;importorg。apache。poi。hssf。eventusermodel。FormatTrackingHSSFListener;importorg。apache。poi。hssf。eventusermodel。HSSFEventFactory;importorg。apache。poi。hssf。eventusermodel。HSSFListener;importorg。apache。poi。hssf。eventusermodel。HSSFRequest;importorg。apache。poi。hssf。eventusermodel。MissingRecordAwareHSSFListener;importorg。apache。poi。hssf。eventusermodel。dummyrecord。LastCellOfRowDummyRecord;importorg。apache。poi。hssf。eventusermodel。dummyrecord。MissingCellDummyRecord;importorg。apache。poi。hssf。model。HSSFFormulaParser;importorg。apache。poi。hssf。record。BOFRecord;importorg。apache。poi。hssf。record。BlankRecord;importorg。apache。poi。hssf。record。BoolErrRecord;importorg。apache。poi。hssf。record。BoundSheetRecord;importorg。apache。poi。hssf。record。FormulaRecord;importorg。apache。poi。hssf。record。LabelRecord;importorg。apache。poi。hssf。record。LabelSSTRecord;importorg。apache。poi。hssf。record。NumberRecord;importorg。apache。poi。hssf。record。Record;importorg。apache。poi。hssf。record。SSTRecord;importorg。apache。poi。hssf。record。StringRecord;importorg。apache。poi。hssf。usermodel。HSSFDataFormatter;importorg。apache。poi。hssf。usermodel。HSSFWorkbook;importorg。apache。poi。poifs。filesystem。POIFSFileSystem;用于解决。xls2003版本大数据量问题publicclassExcelXlsReaderimplementsHSSFListener{privateintminColums1;privatePOIFSFileSystemfs;总行数privateinttotalRows0;上一行row的序号privateintlastRowNumber;上一单元格的序号privateintlastColumnNumber;是否输出formula,还是它对应的值privatebooleanoutputFormulaValuestrue;用于转换formulasprivateEventWorkbookBuilder。SheetRecordCollectingListenerworkbookBuildingListener;excel2003工作簿privateHSSFWorkbookstubWorkbook;privateSSTRecordsstRecord;privateFormatTrackingHSSFListenerformatListener;privatefinalHSSFDataFormatterformatternewHSSFDataFormatter();文件的绝对路径privateStringfilePath;表索引privateintsheetIndex0;privateBoundSheetRecord〔〕orderedBSRs;SuppressWarnings({rawtypes})privateArrayListboundSheetRecordsnewArrayList();privateintnextRow;privateintnextColumn;privatebooleanoutputNextStringRecord;当前行privateintcurRow0;存储一行记录所有单元格的容器privateListStringcellListnewArrayListString();判断整行是否为空行的标记privatebooleanflagfalse;定义列名的行索引privateintheaderIncex1;定义数据的行索引privateintdataIndex2;privateStringsheetName;根据文件流解析paraminputStreamparamheaderIncexparamdataIndexreturnthrowsExceptionpublicintprocess(InputStreaminputStream,intheaderIncex,intdataIndex)throwsException{this。fsnewPOIFSFileSystem(inputStream);returninit(headerIncex,dataIndex);}根据文件路径解析parampathparamheaderIncexparamdataIndexreturnthrowsExceptionpublicintprocess(Stringpath,intheaderIncex,intdataIndex)throwsException{this。fsnewPOIFSFileSystem(newFileInputStream(path));returninit(headerIncex,dataIndex);}遍历excel下所有的sheetparamheaderIncexparamdataIndexreturnthrowsExceptionprivateintinit(intheaderIncex,intdataIndex)throwsException{MissingRecordAwareHSSFListenerlistenernewMissingRecordAwareHSSFListener(this);formatListenernewFormatTrackingHSSFListener(listener);HSSFEventFactoryfactorynewHSSFEventFactory();HSSFRequestrequestnewHSSFRequest();if(outputFormulaValues){request。addListenerForAllRecords(formatListener);}else{workbookBuildingListenernewEventWorkbookBuilder。SheetRecordCollectingListener(formatListener);request。addListenerForAllRecords(workbookBuildingListener);}if(headerIncex0)设置表头行this。headerIncexheaderIncex;if(dataIndex0)设置数据行this。dataIndexdataIndex;factory。processWorkbookEvents(request,fs);返回该excel文件的总行数,不包括首列和空行returntotalRows;}HSSFListener监听方法,处理Record处理每个单元格SuppressWarnings(unchecked)publicvoidprocessRecord(Recordrecord){intthisRow1;intthisColumn1;StringthisStrnull;Stringvaluenull;switch(record。getSid()){caseBoundSheetRecord。sid:boundSheetRecords。add(record);break;caseBOFRecord。sid:开始处理每个sheetBOFRecordbr(BOFRecord)record;if(br。getType()BOFRecord。TYPEWORKSHEET){如果有需要,则建立子工作簿if(workbookBuildingListener!nullstubWorkbooknull){stubWorkbookworkbookBuildingListener。getStubHSSFWorkbook();}if(orderedBSRsnull){orderedBSRsBoundSheetRecord。orderByBofPosition(boundSheetRecords);}sheetNameorderedBSRs〔sheetIndex〕。getSheetname();sheetIndex;}break;caseSSTRecord。sid:sstRecord(SSTRecord)record;break;caseBlankRecord。sid:单元格为空白BlankRecordbrec(BlankRecord)record;thisRowbrec。getRow();thisColumnbrec。getColumn();thisStr;cellList。add(thisColumn,thisStr);break;caseBoolErrRecord。sid:单元格为布尔类型BoolErrRecordberec(BoolErrRecord)record;thisRowberec。getRow();thisColumnberec。getColumn();thisStrberec。getBooleanValue();cellList。add(thisColumn,thisStr);如果里面某个单元格含有值,则标识该行不为空行checkRowIsNull(thisStr);break;caseFormulaRecord。sid:单元格为公式类型FormulaRecordfrec(FormulaRecord)record;thisRowfrec。getRow();thisColumnfrec。getColumn();if(outputFormulaValues){if(Double。isNaN(frec。getValue())){outputNextStringRecordtrue;nextRowfrec。getRow();nextColumnfrec。getColumn();}else{thisStrHSSFFormulaParser。toFormulaString(stubWorkbook,frec。getParsedExpression());}}else{thisStrHSSFFormulaParser。toFormulaString(stubWorkbook,frec。getParsedExpression());}cellList。add(thisColumn,thisStr);如果里面某个单元格含有值,则标识该行不为空行checkRowIsNull(thisStr);break;caseStringRecord。sid:单元格中公式的字符串if(outputNextStringRecord){StringRecordsrec(StringRecord)record;thisStrsrec。getString();thisRownextRow;thisColumnnextColumn;outputNextStringRecordfalse;}break;caseLabelRecord。sid:LabelRecordlrec(LabelRecord)record;curRowthisRowlrec。getRow();thisColumnlrec。getColumn();valuelrec。getValue()。trim();valuevalue。equals()?:value;cellList。add(thisColumn,value。replaceAll(,));如果里面某个单元格含有值,则标识该行不为空行checkRowIsNull(value);break;caseLabelSSTRecord。sid:单元格为字符串类型LabelSSTRecordlsrec(LabelSSTRecord)record;curRowthisRowlsrec。getRow();thisColumnlsrec。getColumn();if(sstRecordnull){cellList。add(thisColumn,);}else{valuesstRecord。getString(lsrec。getSSTIndex())。toString()。trim();valuevalue。equals()?:value;cellList。add(thisColumn,value。replaceAll(,));如果里面某个单元格含有值,则标识该行不为空行checkRowIsNull(value);}break;caseNumberRecord。sid:单元格为数字类型NumberRecordnumrec(NumberRecord)record;curRowthisRownumrec。getRow();thisColumnnumrec。getColumn();第一种方式这个被写死,采用的mdyyh:mm格式,不符合要求valueformatListener。formatNumberDateCell(numrec)。trim();第二种方式,参照formatNumberDateCell里面的实现方法编写DoublevalueDouble((NumberRecord)numrec)。getValue();StringformatStringformatListener。getFormatString(numrec);if(formatString。contains(mdyy)){formatStringyyyyMMddhh:mm:ss;}intformatIndexformatListener。getFormatIndex(numrec);valueformatter。formatRawCellContents(valueDouble,formatIndex,formatString)。trim();valuevalue。equals()?:value;向容器加入列值cellList。add(thisColumn,value。replaceAll(,));如果里面某个单元格含有值,则标识该行不为空行checkRowIsNull(value);break;default:break;}遇到新行的操作if(thisRow!1thisRow!lastRowNumber){lastColumnNumber1;}空值的操作if(recordinstanceofMissingCellDummyRecord){MissingCellDummyRecordmc(MissingCellDummyRecord)record;curRowthisRowmc。getRow();thisColumnmc。getColumn();cellList。add(thisColumn,);}更新行和列的值if(thisRow1)lastRowNumberthisRow;if(thisColumn1)lastColumnNumberthisColumn;行结束时的操作if(recordinstanceofLastCellOfRowDummyRecord){if(minColums0){列值重新置空if(lastColumnNumber1){lastColumnNumber0;}}lastColumnNumber1;if(curRowheaderIncex1){表头行结束时,调用sendHeaderRows()方法sendHeaderRows(filePath,sheetName,sheetIndex,curRow1,cellList);}该行不为空行且该行为数据行if(flagcurRowdataIndex1){每行数据结束时,调用sendDataRows()方法sendDataRows(filePath,sheetName,sheetIndex,curRow1,cellList);totalRows;}清空容器cellList。clear();flagfalse;}}如果里面某个单元格含有值,则标识该行不为空行paramvaluepublicvoidcheckRowIsNull(Stringvalue){if(value!null!。equals(value)){flagtrue;}}表头数据paramfilePathparamsheetNameparamsheetIndexparamcurRowparamcellListpublicvoidsendHeaderRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){}解析数据paramfilePathparamsheetNameparamsheetIndexparamcurRowparamcellListpublicvoidsendDataRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){}} 3、2007及以上版本importjava。io。InputStream;importjava。util。ArrayList;importjava。util。List;importcom。base。infrastructure。log。LoggerManager;importorg。apache。poi。openxml4j。opc。OPCPackage;importorg。apache。poi。ss。usermodel。BuiltinFormats;importorg。apache。poi。ss。usermodel。DataFormatter;importorg。apache。poi。xssf。eventusermodel。XSSFReader;importorg。apache。poi。xssf。model。SharedStringsTable;importorg。apache。poi。xssf。model。StylesTable;importorg。apache。poi。xssf。usermodel。XSSFCellStyle;importorg。apache。poi。xssf。usermodel。XSSFRichTextString;importorg。xml。sax。Attributes;importorg。xml。sax。InputSource;importorg。xml。sax。SAXException;importorg。xml。sax。XMLReader;importorg。xml。sax。helpers。DefaultHandler;importorg。xml。sax。helpers。XMLReaderFactory;2007版本publicclassExcelXlsxReaderextendsDefaultHandler{单元格中的数据可能的数据类型enumCellDataType{BOOL,ERROR,FORMULA,INLINESTR,SSTINDEX,NUMBER,DATE,NULL}共享字符串表privateSharedStringsTablesst;上一次的索引值privateStringlastIndex;文件的绝对路径privateStringfilePath;工作表索引privateintsheetIndex0;sheet名privateStringsheetName;总行数privateinttotalRows0;一行内cell集合privateListStringcellListnewArrayListString();判断整行是否为空行的标记privatebooleanflagfalse;当前行privateintcurRow1;前一个列privateintlastCurCol1;当前列privateintcurCol0;定义该文档一行最大的单元格数,用来补全一行最后可能缺失的单元格privateintmaxcurCol0;定义当前读到的列与上一次读到的列中是否有空值(即该单元格什么也没有输入,连空格都不存在)默认为falseprivatebooleancurflagfalse;T元素标识privatebooleanisTElement;异常信息,如果为空则表示没有异常privateStringexceptionMessage;单元格数据类型,默认为字符串类型privateCellDataTypenextDataTypeCellDataType。SSTINDEX;privatefinalDataFormatterformatternewDataFormatter();单元格日期格式的索引privateshortformatIndex;日期格式字符串privateStringformatString;定义列名的行索引privateintheaderIncex1;定义数据的行索引privateintdataIndex2;单元格privateStylesTablestylesTable;根据文件路径解析parampathparamheaderIncexparamdataIndexreturnthrowsExceptionpublicintprocess(Stringpath,intheaderIncex,intdataIndex)throwsException{OPCPackagepkgOPCPackage。open(path);returninit(pkg,headerIncex,dataIndex);}根据文件流解析(占用内存消耗比文件路径解析大)paraminputStreamparamheaderIncexparamdataIndexreturnthrowsExceptionpublicintprocess(InputStreaminputStream,intheaderIncex,intdataIndex)throwsException{OPCPackagepkgOPCPackage。open(inputStream);returninit(pkg,headerIncex,dataIndex);}遍历工作簿中所有的电子表格并缓存在mySheetList中parampkgparamheaderIncexparamdataIndexreturnthrowsExceptionprivateintinit(OPCPackagepkg,intheaderIncex,intdataIndex)throwsException{XSSFReaderxssfReadernewXSSFReader(pkg);stylesTablexssfReader。getStylesTable();SharedStringsTablesstxssfReader。getSharedStringsTable();XMLReaderparserXMLReaderFactory。createXMLReader(org。apache。xerces。parsers。SAXParser);this。sstsst;parser。setContentHandler(this);XSSFReader。SheetIteratorsheets(XSSFReader。SheetIterator)xssfReader。getSheetsData();while(sheets。hasNext()){遍历sheetcurRow1;标记初始行为第一行if(headerIncex0)this。headerIncexheaderIncex;设置表头行if(dataIndex0)this。dataIndexdataIndex;设置数据行sheetIndex;InputStreamsheetsheets。next();sheets。next()和sheets。getSheetName()不能换位置,否则sheetName报错sheetNamesheets。getSheetName();InputSourcesheetSourcenewInputSource(sheet);parser。parse(sheetSource);解析excel的每条记录,在这个过程中startElement()、characters()、endElement()这三个函数会依次执行sheet。close();}pkg。close();returntotalRows;返回该excel文件的总行数,不包括首列和空行}第一个执行paramuriparamlocalNameparamnameparamattributesthrowsSAXExceptionOverridepublicvoidstartElement(Stringuri,StringlocalName,Stringname,Attributesattributes)throwsSAXException{c单元格if(c。equals(name)){当前单元格的位置Stringrattributes。getValue(r);intfirstDigit1;for(intc0;cr。length();c){if(Character。isDigit(r。charAt(c))){firstDigitc;break;}}curColnameToColumn(r。substring(0,firstDigit));获取当前读取的列数设定单元格类型this。setNextDataType(attributes);}当元素为t时if(t。equals(name)){isTElementtrue;}else{isTElementfalse;}置空lastIndex;}第二个执行得到单元格对应的索引值或是内容值如果单元格类型是字符串、INLINESTR、数字、日期,lastIndex则是索引值如果单元格类型是布尔值、错误、公式,lastIndex则是内容值paramchparamstartparamlengththrowsSAXExceptionOverridepublicvoidcharacters(char〔〕ch,intstart,intlength)throwsSAXException{lastIndexnewString(ch,start,length);}第三个执行paramuriparamlocalNameparamnamethrowsSAXExceptionOverridepublicvoidendElement(Stringuri,StringlocalName,Stringname)throwsSAXException{t元素也包含字符串if(isTElement){这个程序没经过将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符StringvaluelastIndex。trim();cellList。add(curCol,value。replaceAll(,));isTElementfalse;如果里面某个单元格含有值,则标识该行不为空行if(value!null!。equals(value)){flagtrue;}}elseif(v。equals(name)){v单元格的值,如果单元格是字符串,则v标签的值为该字符串在SST中的索引Stringvaluethis。getDataValue(lastIndex。trim(),);根据索引值获取对应的单元格值补全单元格之间的空单元格if(curCollastCurCol1){curflagtrue;}for(intilastCurCol;icurCol;i){if(curflagilastCurCol){cellList。add(i,);}}if(curCol1){lastCurColcurCol;}cellList。add(curCol,value。replaceAll(,));如果里面某个单元格含有值,则标识该行不为空行if(value!null!。equals(value。trim())){flagtrue;}}else{如果标签名称为row,这说明已到行尾,调用optRows()方法if(row。equals(name)){默认第一行为表头,以该行单元格数目为最大数目if(curRowheaderIncex){sendHeaderRows(filePath,sheetName,sheetIndex,curRow,cellList);maxcurColcellList。size()1;}补全一行尾部可能缺失的单元格if(maxcurCollastCurCol){curflagtrue;}for(intilastCurCol;imaxcurCol;i){if(curflagflag){cellList。add(i,);}}if(flagcurRowdataIndex){该行不为空行且该行不是第一行,则发送(第一行为列名,不需要)sendDataRows(filePath,sheetName,sheetIndex,curRow,cellList);totalRows;}cellList。clear();curRow;curCol0;lastCurCol1;flagfalse;}}}处理数据类型paramattributespublicvoidsetNextDataType(Attributesattributes){nextDataTypeCellDataType。NUMBER;cellType为空,则表示该单元格类型为数字formatIndex1;formatStringnull;StringcellTypeattributes。getValue(t);单元格类型StringcellStyleStrattributes。getValue(s);StringcolumnDataattributes。getValue(r);获取单元格的位置,如A1,B1if(b。equals(cellType)){处理布尔值nextDataTypeCellDataType。BOOL;}elseif(e。equals(cellType)){处理错误nextDataTypeCellDataType。ERROR;}elseif(inlineStr。equals(cellType)){nextDataTypeCellDataType。INLINESTR;}elseif(s。equals(cellType)){处理字符串nextDataTypeCellDataType。SSTINDEX;}elseif(str。equals(cellType)){nextDataTypeCellDataType。FORMULA;}if(cellStyleStr!null){处理日期intstyleIndexInteger。parseInt(cellStyleStr);XSSFCellStylestylestylesTable。getStyleAt(styleIndex);formatIndexstyle。getDataFormat();formatStringstyle。getDataFormatString();if(formatStringnull){nextDataTypeCellDataType。NULL;formatStringBuiltinFormats。getBuiltinFormat(formatIndex);}elseif(formatString。contains(mdyy)){nextDataTypeCellDataType。DATE;formatStringyyyyMMddhh:mm:ss;}}}对解析出来的数据进行类型处理paramvalue单元格的值,value代表解析:BOOL的为0或1,ERROR的为内容值,FORMULA的为内容值,INLINESTR的为索引值需转换为内容值,SSTINDEX的为索引值需转换为内容值,NUMBER为内容值,DATE为内容值paramthisStr一个空字符串returnpublicStringgetDataValue(Stringvalue,StringthisStr){switch(nextDataType){这几个的顺序不能随便交换,交换了很可能会导致数据错误caseBOOL:布尔值charfirstvalue。charAt(0);thisStrfirst0?FALSE:TRUE;break;caseERROR:错误thisStrERROR:value。toString();break;caseFORMULA:公式thisStrvalue。toString();break;caseINLINESTR:XSSFRichTextStringrtsinewXSSFRichTextString(value。toString());thisStrrtsi。toString();rtsinull;break;caseSSTINDEX:字符串StringsstIndexvalue。toString();try{intidxInteger。parseInt(sstIndex);XSSFRichTextStringrtssnewXSSFRichTextString(sst。getEntryAt(idx));根据idx索引值获取内容值thisStrrtss。toString();rtssnull;}catch(NumberFormatExceptionex){thisStrvalue。toString();}break;caseNUMBER:数字if(formatString!null){thisStrformatter。formatRawCellContents(Double。parseDouble(value),formatIndex,formatString)。trim();}else{thisStrvalue;}thisStrthisStr。replace(,)。trim();break;caseDATE:日期thisStrformatter。formatRawCellContents(Double。parseDouble(value),formatIndex,formatString);对日期字符串作特殊处理,去掉TthisStrthisStr。replace(T,);break;default:thisStr;break;}returnthisStr;}publicintcountNullCell(Stringref,StringpreRef){excel2007最大行数是1048576,最大列数是16384,最后一列列名是XFDStringxfdref。replaceAll(d,);Stringxfd1preRef。replaceAll(d,);xfdfillChar(xfd,3,,true);xfd1fillChar(xfd1,3,,true);char〔〕letterxfd。toCharArray();char〔〕letter1xfd1。toCharArray();intres(letter〔0〕letter1〔0〕)2626(letter〔1〕letter1〔1〕)26(letter〔2〕letter1〔2〕);returnres1;}publicStringfillChar(Stringstr,intlen,charlet,booleanisPre){intlen1str。length();if(len1len){if(isPre){for(inti0;i(lenlen1);i){strletstr;}}else{for(inti0;i(lenlen1);i){strstrlet;}}}returnstr;}privateintnameToColumn(Stringname){intcolumn1;for(inti0;iname。length();i){intcname。charAt(i);column(column1)26cA;}returncolumn;}returntheexceptionMessagepublicStringgetExceptionMessage(){returnexceptionMessage;}表头数据paramfilePathparamsheetNameparamsheetIndexparamcurRowparamcellListpublicvoidsendHeaderRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){}解析数据paramfilePathparamsheetNameparamsheetIndexparamcurRowparamcellListpublicvoidsendDataRows(StringfilePath,StringsheetName,intsheetIndex,intcurRow,ListStringcellList){}} 三、导出importorg。apache。poi。ss。usermodel。;importorg。apache。poi。xssf。streaming。SXSSFWorkbook;importorg。apache。poi。xssf。usermodel。XSSFCellStyle;importorg。apache。poi。xssf。usermodel。XSSFFont;importjavax。servlet。http。HttpServletResponse;importjava。io。ByteArrayOutputStream;importjava。io。OutputStream;importjava。net。URLEncoder;importjava。util。List;importjava。util。Map;EXCEL导出publicclassBigExcelExportUtil{私有构造函数privateBigExcelExportUtil(){}构造EXCEL,并响应客户端功能详细描述paramlistValuesparamfileNameparamsheetNameparamcellTitleparamcellValueparamressee〔类、类方法、类成员〕publicstaticvoidbuildXSLXExcel(ListMapString,ObjectlistValues,StringfileName,StringsheetName,String〔〕cellTitle,String〔〕cellValue,HttpServletResponseres){byte〔〕bytesbuildXSLXExcelWithSheetName(listValues,sheetName,cellTitle,cellValue);if(0bytes。length){return;}writeDocResponse(res,bytes,fileName);}构建EXCEL功能详细描述paramlistValuesparamsheetNameparamcellTitleparamcellValuesee〔类、类方法、类成员〕publicstaticbyte〔〕buildXSLXExcelWithSheetName(ListMapString,ObjectlistValues,StringsheetName,String〔〕cellTitle,String〔〕cellValue){try(ByteArrayOutputStreamoutStreamnewByteArrayOutputStream();SXSSFWorkbookworkBookcreateExcelBook(listValues,sheetName,cellTitle,cellValue);){workBook。write(outStream);outStream。flush();workBook。dispose();returnoutStream。toByteArray();}catch(Exceptione){e。printStackTrace();returnnewbyte〔0〕;}}生成WorkBook功能详细描述paramlistValuesparamsheetNameparamcellTitleparamcellValuereturnsee〔类、类方法、类成员〕privatestaticSXSSFWorkbookcreateExcelBook(ListMapString,ObjectlistValues,StringsheetName,String〔〕cellTitle,String〔〕cellValue){创建工作薄SXSSFWorkbookworkBooknewSXSSFWorkbook();SheetsheetworkBook。createSheet();工作簿名称workBook。setSheetName(0,sheetName);字体设置FontfontworkBook。createFont();font。setColor(XSSFFont。COLORNORMAL);font。setBoldweight(XSSFFont。BOLDWEIGHTBOLD);font。setBold(true);创建格式XSSFCellStylecellStyle(XSSFCellStyle)workBook。createCellStyle();cellStyle。setFont(font);cellStyle。setAlignment(HSSFCellStyle。ALIGNCENTER);cellStyle。setAlignment(HorizontalAlignment。CENTER);cellStyle。setVerticalAlignment(HSSFCellStyle。VERTICALCENTER);cellStyle。setVerticalAlignment(VerticalAlignment。CENTER);创建第一行标题RowtitleRowsheet。createRow((short)0);for(inti0;icellTitle。length;i){创建第1行标题单元格sheet。setColumnWidth(i,20256);XSSFCellcelltitleRow。createCell(i,0);CellcelltitleRow。createCell(i,CellType。STRING);cell。setCellStyle(cellStyle);cell。setCellType(XSSFCell。CELLTYPESTRING);cell。setCellType(CellType。STRING);cell。setCellValue(cellTitle〔i〕);}第二行开始写入数据if(listValues!nulllistValues。size()0){创建格式XSSFCellStylestyle(XSSFCellStyle)workBook。createCellStyle();遍历列表数据for(inti0;ilistValues。size();i){Rowrowsheet。createRow(i1);setRow(cellTitle,cellValue,workBook,sheet,style,listValues。get(i),i,row);}}returnworkBook;}privatestaticvoidsetRow(String〔〕cellTitle,String〔〕cellValue,SXSSFWorkbookworkBook,Sheetsheet,XSSFCellStylestyle,MapString,Objectmap,intline,Rowrow){for(intj0;jcellTitle。length;j){在上面行索引0的位置创建单元格XSSFCellcelltitleRow。createCell(i,0);Cellcellrow。createCell(j,CellType。STRING);定义单元格为字符串类型cell。setCellType(XSSFCell。CELLTYPESTRING);cell。setCellType(CellType。STRING);取出列表值cell。setCellValue(getMapString(map,cellValue〔j〕));style。setAlignment(XSSFCellStyle。ALIGNCENTER);style。setAlignment(HorizontalAlignment。CENTER);cell。setCellStyle(style);}}输出文件到客户端功能详细描述paramrsphttp响应对象parambytesparamfileNamesee〔类、类方法、类成员〕publicstaticvoidwriteDocResponse(HttpServletResponsersp,byte〔〕bytes,StringfileName){try(OutputStreamoutrsp。getOutputStream();){扩展名获取ContentTypersp。setContentType(applicationvnd。msexcel);StringfileNameURLURLEncoder。encode(fileName,UTF8);StringcontentHeaderattachment;filenamefileNameURL;filenameutf8fileNameURL;rsp。setHeader(Contentdisposition,contentHeader);文件写入out。write(bytes,0,bytes。length);}catch(Exceptione){e。printStackTrace();}}publicstaticStringgetMapString(Mapmap,Stringkey){returnmap。get(key)null?null:String。valueOf(map。get(key));}}