该系列为java工具类系列,主要展示100个常用的java工具类。 此文重点讲述:多种方式解析Excel。 本文目录:通过List生成Excel文件解析Excel文件(入参是MultipartFile)解析Excel文件(入参是Excel本地路径) 一、通过List生成Excel文件importorg。apache。poi。ss。usermodel。HorizontalAlignment;importorg。apache。poi。ss。util。CellRangeAddress;importorg。apache。poi。xssf。usermodel。;importjava。io。File;importjava。io。FileOutputStream;importjava。io。IOException;importjava。text。SimpleDateFormat;importjava。util。;Author程序幻境Date20221119Version1。0classExcelUtils{privatestaticExcelUtilsinstancenewExcelUtils();privateExcelUtils(){}publicstaticExcelUtilsgetInstance(){returninstance;}将ListMapString,Object类型的数据导出为Excel默认Excel文件的输出路径为项目根目录下文件名为filename时间戳。xlsxparammapList数据源(通常为数据库查询数据)paramfilename文件名前缀,实际文件名后会加上日期paramtitle表格首行标题return文件输出路径publicStringcreateExcel(ListMapString,ObjectmapList,Stringfilename,Stringtitle){获取数据源的key,用于获取列数及设置标题MapString,ObjectmapmapList。get(0);SetStringstringSetmap。keySet();ArrayListStringheadListnewArrayList(stringSet);定义一个新的工作簿XSSFWorkbookwbnewXSSFWorkbook();创建一个Sheet页XSSFSheetsheetwb。createSheet(title);设置行高sheet。setDefaultRowHeight((short)(2256));为有数据的每列设置列宽for(inti0;iheadList。size();i){sheet。setColumnWidth(i,8000);}设置单元格字体样式XSSFFontfontwb。createFont();font。setFontName(等线);font。setFontHeightInPoints((short)16);在sheet里创建第一行,并设置单元格内容为title(标题)XSSFRowtitleRowsheet。createRow(0);XSSFCelltitleCelltitleRow。createCell(0);titleCell。setCellValue(title);合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列,截至列sheet。addMergedRegion(newCellRangeAddress(0,0,0,headList。size()1));创建单元格文字居中样式并设置标题单元格居中XSSFCellStylecellStylewb。createCellStyle();cellStyle。setAlignment(HorizontalAlignment。CENTER);titleCell。setCellStyle(cellStyle);获得表格第二行XSSFRowrowsheet。createRow(1);根据数据源信息给第二行每一列设置标题for(inti0;iheadList。size();i){XSSFCellcellrow。createCell(i);cell。setCellValue(headList。get(i));}XSSFRowrows;XSSFCellcells;循环拿到的数据给所有行每一列设置对应的值for(inti0;imapList。size();i){在这个sheet页里创建一行rowssheet。createRow(i2);给该行数据赋值for(intj0;jheadList。size();j){StringvaluemapList。get(i)。get(headList。get(j))。toString();cellsrows。createCell(j);cells。setCellValue(value);}}DatedatenewDate();SimpleDateFormatdateFormatnewSimpleDateFormat(yyyyMMdd);使用项目根目录,文件名加上时间戳StringpathSystem。getProperty(user。dir)filenamedateFormat。format(date)。xlsx;try{FilefilenewFile(path);FileOutputStreamfileOutputStreamnewFileOutputStream(file);wb。write(fileOutputStream);fileOutputStream。close();}catch(IOExceptione){e。printStackTrace();}returnpath;}publicstaticvoidmain(String〔〕args){ListMapString,ObjectlistnewArrayList();for(inti0;i3;i){MapString,ObjectmapnewHashMap();map。put(测试1,i);map。put(测试2,i);map。put(测试3,i);list。add(map);}ExcelUtils。getInstance()。createExcel(list,data,测试数据);}} 二、解析Excel文件(入参是Excel本地路径)Author程序幻境Date20221119Version1。0importjava。io。IOException;importjava。io。InputStream;importjava。text。DecimalFormat;importjava。text。SimpleDateFormat;importjava。util。ArrayList;importjava。util。Date;importjava。util。List;importorg。apache。log4j。Logger;importorg。apache。poi。hssf。usermodel。HSSFDataFormat;importorg。apache。poi。hssf。usermodel。HSSFDateUtil;importorg。apache。poi。hssf。usermodel。HSSFWorkbook;importorg。apache。poi。ss。usermodel。;importorg。apache。poi。xssf。usermodel。XSSFWorkbook;importorg。springframework。web。multipart。MultipartFile;解析excel上传数据publicclassExcelUtil{privatestaticfinalLoggerlogLogger。getLogger(ExcelUtil。class);解析excelparamfilereturnthrowsIOExceptionpublicstaticListString〔〕getExcelData(MultipartFilefile)throwsIOException{checkFile(file);获得Workbook工作薄对象WorkbookworkbookgetWorkBook(file);创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回ListString〔〕listnewArrayListString〔〕();if(workbook!null){for(intsheetNum0;sheetNumworkbook。getNumberOfSheets();sheetNum){获得当前sheet工作表Sheetsheetworkbook。getSheetAt(sheetNum);if(sheetnull){continue;}获得当前sheet的开始行intfirstRowNumsheet。getFirstRowNum();获得当前sheet的结束行intlastRowNumsheet。getLastRowNum();循环除了所有行,如果要循环除第一行以外的就firstRowNum1for(introwNumfirstRowNum;rowNumlastRowNum;rowNum){获得当前行Rowrowsheet。getRow(rowNum);if(rownull){continue;}获得当前行的开始列intfirstCellNumrow。getFirstCellNum();获得当前行的列数intlastCellNumrow。getLastCellNum();String〔〕cellsnewString〔row。getLastCellNum()〕;循环当前行for(intcellNumfirstCellNum;cellNumlastCellNum;cellNum){Cellcellrow。getCell(cellNum);cells〔cellNum〕getCellValue(cell);}list。add(cells);}}}returnlist;}检查文件paramfilethrowsIOExceptionpublicstaticvoidcheckFile(MultipartFilefile)throwsIOException{判断文件是否存在if(nullfile){log。error(文件不存在!);}获得文件名StringfileNamefile。getOriginalFilename();判断文件是否是excel文件if(!fileName。endsWith(xls)!fileName。endsWith(xlsx)){log。error(fileName不是excel文件);}}publicstaticWorkbookgetWorkBook(MultipartFilefile){获得文件名StringfileNamefile。getOriginalFilename();创建Workbook工作薄对象,表示整个excelWorkbookworkbooknull;try{获取excel文件的io流InputStreamisfile。getInputStream();根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象if(fileName。endsWith(xls)){2003workbooknewHSSFWorkbook(is);}elseif(fileName。endsWith(xlsx)){2007及2007以上workbooknewXSSFWorkbook(is);}}catch(IOExceptione){log。error(e。getMessage());}returnworkbook;}publicstaticStringgetCellValue(Cellcell){StringcellValue;if(cellnull){returncellValue;}判断数据的类型switch(cell。getCellType()){caseCell。CELLTYPENUMERIC:数字cellValuestringDateProcess(cell);break;caseCell。CELLTYPESTRING:字符串cellValueString。valueOf(cell。getStringCellValue());break;caseCell。CELLTYPEBOOLEAN:BooleancellValueString。valueOf(cell。getBooleanCellValue());break;caseCell。CELLTYPEFORMULA:公式cellValueString。valueOf(cell。getCellFormula());break;caseCell。CELLTYPEBLANK:空值cellValue;break;caseCell。CELLTYPEERROR:故障cellValue非法字符;break;default:cellValue未知类型;break;}returncellValue;}publicstaticStringstringDateProcess(Cellcell){StringresultnewString();if(HSSFDateUtil。isCellDateFormatted(cell)){处理日期格式、时间格式SimpleDateFormatsdfnull;if(cell。getCellStyle()。getDataFormat()HSSFDataFormat。getBuiltinFormat(h:mm)){sdfnewSimpleDateFormat(HH:mm);}else{日期sdfnewSimpleDateFormat(yyyyMMddhh:mm:ss);}Datedatecell。getDateCellValue();resultsdf。format(date);}elseif(cell。getCellStyle()。getDataFormat()58){处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)SimpleDateFormatsdfnewSimpleDateFormat(yyyyMMddhh:mm:ss);doublevaluecell。getNumericCellValue();Datedateorg。apache。poi。ss。usermodel。DateUtil。getJavaDate(value);resultsdf。format(date);}else{doublevaluecell。getNumericCellValue();CellStylestylecell。getCellStyle();DecimalFormatformatnewDecimalFormat();Stringtempstyle。getDataFormatString();单元格设置成常规if(temp。equals(General)){format。applyPattern();}resultformat。format(value);}returnresult;}} 三、解析Excel文件(入参是MultipartFile) MultipartFile是一种可以接收使用多种请求方式来进行上传文件的代表形式。 MultipartFile是一个接口,继承自InputStreamSource,封装了getInputStream方法,因此MultipartFile文件可以转换为输入流。Author程序幻境Date20221119Version1。0importjava。io。FileInputStream;importjava。io。IOException;importjava。io。InputStream;importjava。text。DecimalFormat;importjava。text。SimpleDateFormat;importjava。util。ArrayList;importjava。util。Date;importjava。util。List;importorg。apache。log4j。Logger;importorg。apache。poi。hssf。usermodel。HSSFDataFormat;importorg。apache。poi。hssf。usermodel。HSSFDateUtil;importorg。apache。poi。hssf。usermodel。HSSFWorkbook;importorg。apache。poi。ss。usermodel。;importorg。apache。poi。xssf。usermodel。XSSFWorkbook;importorg。springframework。web。multipart。MultipartFile;解析excel上传数据publicclassExcelUtil{privatestaticfinalLoggerlogLogger。getLogger(ExcelUtil。class);publicstaticvoidmain(String〔〕args){try{getExcelData(C:UsersZXCDesktop1。xlsx);}catch(IOExceptione){e。printStackTrace();}}解析excelparamfilereturnthrowsIOExceptionpublicstaticListString〔〕getExcelData(StringfilePath)throwsIOException{通过输入流,读取excel文件FileInputStreaminputnewFileInputStream(filePath);将输入流传入WorkbookWorkbookworkbooknewXSSFWorkbook(input);创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回ListString〔〕listnewArrayListString〔〕();if(workbook!null){for(intsheetNum0;sheetNumworkbook。getNumberOfSheets();sheetNum){获得当前sheet工作表Sheetsheetworkbook。getSheetAt(sheetNum);if(sheetnull){continue;}获得当前sheet的开始行intfirstRowNumsheet。getFirstRowNum();获得当前sheet的结束行intlastRowNumsheet。getLastRowNum();循环除了所有行,如果要循环除第一行以外的就firstRowNum1for(introwNumfirstRowNum;rowNumlastRowNum;rowNum){获得当前行Rowrowsheet。getRow(rowNum);if(rownull){continue;}获得当前行的开始列intfirstCellNumrow。getFirstCellNum();获得当前行的列数intlastCellNumrow。getLastCellNum();String〔〕cellsnewString〔row。getLastCellNum()〕;循环当前行for(intcellNumfirstCellNum;cellNumlastCellNum;cellNum){Cellcellrow。getCell(cellNum);cells〔cellNum〕getCellValue(cell);}list。add(cells);}}}returnlist;}检查文件paramfilethrowsIOExceptionpublicstaticvoidcheckFile(MultipartFilefile)throwsIOException{判断文件是否存在if(nullfile){log。error(文件不存在!);}获得文件名StringfileNamefile。getOriginalFilename();判断文件是否是excel文件if(!fileName。endsWith(xls)!fileName。endsWith(xlsx)){log。error(fileName不是excel文件);}}publicstaticWorkbookgetWorkBook(MultipartFilefile){获得文件名StringfileNamefile。getOriginalFilename();创建Workbook工作薄对象,表示整个excelWorkbookworkbooknull;try{获取excel文件的io流InputStreamisfile。getInputStream();根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象if(fileName。endsWith(xls)){2003workbooknewHSSFWorkbook(is);}elseif(fileName。endsWith(xlsx)){2007及2007以上workbooknewXSSFWorkbook(is);}}catch(IOExceptione){log。error(e。getMessage());}returnworkbook;}publicstaticStringgetCellValue(Cellcell){StringcellValue;if(cellnull){returncellValue;}判断数据的类型switch(cell。getCellType()){caseCell。CELLTYPENUMERIC:数字cellValuestringDateProcess(cell);break;caseCell。CELLTYPESTRING:字符串cellValueString。valueOf(cell。getStringCellValue());break;caseCell。CELLTYPEBOOLEAN:BooleancellValueString。valueOf(cell。getBooleanCellValue());break;caseCell。CELLTYPEFORMULA:公式cellValueString。valueOf(cell。getCellFormula());break;caseCell。CELLTYPEBLANK:空值cellValue;break;caseCell。CELLTYPEERROR:故障cellValue非法字符;break;default:cellValue未知类型;break;}returncellValue;}publicstaticStringstringDateProcess(Cellcell){StringresultnewString();if(HSSFDateUtil。isCellDateFormatted(cell)){处理日期格式、时间格式SimpleDateFormatsdfnull;if(cell。getCellStyle()。getDataFormat()HSSFDataFormat。getBuiltinFormat(h:mm)){sdfnewSimpleDateFormat(HH:mm);}else{日期sdfnewSimpleDateFormat(yyyyMMddhh:mm:ss);}Datedatecell。getDateCellValue();resultsdf。format(date);}elseif(cell。getCellStyle()。getDataFormat()58){处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)SimpleDateFormatsdfnewSimpleDateFormat(yyyyMMddhh:mm:ss);doublevaluecell。getNumericCellValue();Datedateorg。apache。poi。ss。usermodel。DateUtil。getJavaDate(value);resultsdf。format(date);}else{doublevaluecell。getNumericCellValue();CellStylestylecell。getCellStyle();DecimalFormatformatnewDecimalFormat();Stringtempstyle。getDataFormatString();单元格设置成常规if(temp。equals(General)){format。applyPattern();}resultformat。format(value);}returnresult;}} 本文仅供个人记录,大家可以借鉴,每行代码都是自己手打,亲测可直接粘贴执行,如有任何问题可在评论区提问,欢迎大家交流。 编辑人:程序幻境 码字不易,不喜勿踩 写代码使我快乐