| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- package com.zksy.utils;
- import com.zksy.common.exception.ServiceException;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- import org.apache.poi.ss.usermodel.*;
- import org.apache.poi.ss.util.CellRangeAddress;
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
- import org.springframework.web.multipart.MultipartFile;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.lang.reflect.Field;
- import java.text.DecimalFormat;
- import java.util.*;
- import java.util.regex.Pattern;
- public class MergeReadsExcelUtil<T> {
- /**
- * 读取excel数据
- * @param file
- */
- public static <T> List<Map<String,String>> readExcelToObj(MultipartFile file, int headerColumn, int number, int headerLine, Class<T> classEntity) {
- Workbook wb = null;
- String fileName = file.getOriginalFilename();//获取文件名
- List<Map<String,String>> result = null;
- try {
- if (!validateExcel(fileName)) {// 验证文件名是否合格
- return null;
- }
- boolean isExcel2003 = true;// 根据文件名判断文件是2003版本还是2007版本
- if (isExcel2007(fileName)) {
- isExcel2003 = false;
- }
- if (isExcel2003) {// 当excel是2003时,创建excel2003
- wb = new HSSFWorkbook(file.getInputStream());
- } else {// 当excel是2007时,创建excel2007
- wb = new XSSFWorkbook(file.getInputStream());
- }
- result = readExcel(wb, 0, 1, 0, headerColumn, number, headerLine,classEntity);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return result;
- }
- /**
- * 读取excel文件
- * @param wb
- * @param sheetIndex sheet页下标:从0开始
- * @param startReadLine 开始读取的行:从0开始
- * @param tailLine 去除最后读取的行
- */
- private static <T> List<Map<String,String>> readExcel(Workbook wb, int sheetIndex, int startReadLine, int tailLine,int headerColumn,int number,int headerLine,Class<T> classEntity) {
- Sheet sheet = wb.getSheetAt(sheetIndex);
- Row row = null;
- List<Map<String,String>> result = new ArrayList<Map<String,String>>();
- List<String> stringList = getEntityProp(classEntity);
- List<String> serialNumberColumn = new ArrayList<>();
- /*if(sheet.getRow(sheet.getFirstRowNum()).getLastCellNum() != headerColumn){
- throw new ServiceException("导入模板不正确");
- }*/
- for(int i=startReadLine; i<sheet.getLastRowNum()-tailLine+1; i++) {
- row = sheet.getRow(i);
- Map<String,String> map = new HashMap<String,String>();
- for(Cell c : row) {
- String returnStr = "";
- boolean isMerge = isMergedRegion(sheet, i, c.getColumnIndex());
- //判断是否具有合并单元格
- if(isMerge) {
- String rs = getMergedRegionValue(sheet, row.getRowNum(), c.getColumnIndex());
- returnStr = rs;
- }else {
- //设置单元格类型
- returnStr = getCellValue(c);
- }
- //将值存进list
- serialNumberColumn.add(returnStr);
- if(serialNumberColumn.contains("序号")){
- //去掉第一列数据
- if(c.getColumnIndex() <= headerColumn && c.getColumnIndex() >= number && i > headerLine) {
- map.put(stringList.get(c.getColumnIndex() - 1), returnStr);
- }
- }else{
- //不去第一列数据
- if(c.getColumnIndex() < headerColumn && i > headerLine) {
- map.put(stringList.get(c.getColumnIndex()), returnStr);
- }
- }
- }
- if(map.size() > 0) {
- result.add(map);
- }
- }
- if(result.size() > 0 && result.get(0).size() != headerColumn){
- throw new ServiceException("导入模板不正确");
- }
- return result;
- }
- //错误信息接收器
- private static String errorMsg;
- public static boolean validateExcel(String filePath) {
- if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
- errorMsg = "文件名不是excel格式";
- return false;
- }
- return true;
- }
- // @描述:是否是2003的excel,返回true是2003
- public static boolean isExcel2003(String filePath) {
- return filePath.matches("^.+\\.(?i)(xls)$");
- }
- //@描述:是否是2007的excel,返回true是2007
- public static boolean isExcel2007(String filePath) {
- return filePath.matches("^.+\\.(?i)(xlsx)$");
- }
- public static <T> List<String> getEntityProp(Class<T> clazz) {
- Field[] fields = clazz.getDeclaredFields();
- List<String> fieldNames = new ArrayList<>();
- for (Field field : fields) {
- fieldNames.add(field.getName());
- }
- fieldNames.remove("serialVersionUID");
- fieldNames.remove("id");
- return fieldNames;
- }
- /**
- * 获取合并单元格的值
- * @param sheet
- * @param row
- * @param column
- * @return
- */
- public static String getMergedRegionValue(Sheet sheet, int row, int column){
- int sheetMergeCount = sheet.getNumMergedRegions();
- for(int i = 0 ; i < sheetMergeCount ; i++){
- CellRangeAddress ca = sheet.getMergedRegion(i);
- int firstColumn = ca.getFirstColumn();
- int lastColumn = ca.getLastColumn();
- int firstRow = ca.getFirstRow();
- int lastRow = ca.getLastRow();
- if(row >= firstRow && row <= lastRow){
- if(column >= firstColumn && column <= lastColumn){
- Row fRow = sheet.getRow(firstRow);
- Cell fCell = fRow.getCell(firstColumn);
- return getCellValue(fCell) ;
- }
- }
- }
- return null ;
- }
- /**
- * 判断合并了行
- * @param sheet
- * @param row
- * @param column
- * @return
- */
- private boolean isMergedRow(Sheet sheet,int row ,int column) {
- int sheetMergeCount = sheet.getNumMergedRegions();
- for (int i = 0; i < sheetMergeCount; i++) {
- CellRangeAddress range = sheet.getMergedRegion(i);
- int firstColumn = range.getFirstColumn();
- int lastColumn = range.getLastColumn();
- int firstRow = range.getFirstRow();
- int lastRow = range.getLastRow();
- if(row == firstRow && row == lastRow){
- if(column >= firstColumn && column <= lastColumn){
- return true;
- }
- }
- }
- return false;
- }
- /**
- * 判断指定的单元格是否是合并单元格
- * @param sheet
- * @param row 行下标
- * @param column 列下标
- * @return
- */
- private static boolean isMergedRegion(Sheet sheet, int row, int column) {
- int sheetMergeCount = sheet.getNumMergedRegions();
- for (int i = 0; i < sheetMergeCount; i++) {
- CellRangeAddress range = sheet.getMergedRegion(i);
- int firstColumn = range.getFirstColumn();
- int lastColumn = range.getLastColumn();
- int firstRow = range.getFirstRow();
- int lastRow = range.getLastRow();
- if(row >= firstRow && row <= lastRow){
- if(column >= firstColumn && column <= lastColumn){
- return true;
- }
- }
- }
- return false;
- }
- /**
- * 判断sheet页中是否含有合并单元格
- * @param sheet
- * @return
- */
- private boolean hasMerged(Sheet sheet) {
- return sheet.getNumMergedRegions() > 0 ? true : false;
- }
- /**
- * 合并单元格
- * @param sheet
- * @param firstRow 开始行
- * @param lastRow 结束行
- * @param firstCol 开始列
- * @param lastCol 结束列
- */
- private void mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
- sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
- }
- /**
- * 获取单元格的值
- * @param cell
- * @return
- */
- public static String getCellValue(Cell cell){
- if(cell == null) {
- return "";
- }
- if(cell.getCellType() == CellType.STRING){
- return cell.getStringCellValue();
- }else if(cell.getCellType() == CellType.BOOLEAN){
- return String.valueOf(cell.getBooleanCellValue());
- }else if(cell.getCellType() == CellType.FORMULA){
- return convertToPercentage(cell);
- }else if(cell.getCellType() == CellType.NUMERIC){
- double numericValue = cell.getNumericCellValue();
- DecimalFormat df = new DecimalFormat("0"); // 设置格式化模式,保留小数点后的所有位数
- // 判断是否为科学计数法
- if(String.valueOf(numericValue).contains("E")) {
- DataFormatter dataFormatter = new DataFormatter();
- String formattedValue = dataFormatter.formatCellValue(cell); // 使用 DataFormatter 获取格式化后的值
- return formattedValue;
- }/*else if(String.valueOf(numericValue).contains("-")){
- //时间格式
- DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("d-LLL-yyyy", Locale.CHINESE);
- LocalDate date = LocalDate.parse(cell.toString(), inputFormatter);
- return date.toString();
- } */else {
- String formattedValue = df.format(numericValue); // 格式化数值为完整形式
- return formattedValue;
- }
- /* String s = cell.getNumericCellValue() + "";
- // 去掉尾巴上的小数点0
- if (Pattern.matches(".*\\.0*", s)) {
- return s.split("\\.")[0];
- } else {
- return s;
- }*/
- }
- return "";
- }
- public static String convertToPercentage(Cell cell) {
- try {
- if (cell.getCellType() == CellType.FORMULA) {
- String s = cell.getNumericCellValue() + "";
- // 去掉尾巴上的小数点0
- if (Pattern.matches(".*\\.0*", s)) {
- return s.split("\\.")[0];
- } else if(s.contains("E")){
- DecimalFormat decimalFormat = new DecimalFormat("0");
- String decimalNumber = decimalFormat.format(Double.parseDouble(s));
- return decimalNumber;
- }else{
- return s;
- }
- /*double value = cell.getNumericCellValue();
- return String.format("%.2f%%", value * 100); // 保留两位小数*/
- }
- }catch (Exception e){
- //return "0%"; // 如果不是数字类型,返回"NaN%"
- }
- return null;
- }
- /**
- * 从excel读取内容
- */
- public static void readContent(String fileName) {
- boolean isE2007 = false; //判断是否是excel2007格式
- if(fileName.endsWith("xlsx")) {
- isE2007 = true;
- }
- try {
- InputStream input = new FileInputStream(fileName); //建立输入流
- Workbook wb = null;
- //根据文件格式(2003或者2007)来初始化
- if(isE2007) {
- wb = new XSSFWorkbook(input);
- } else {
- wb = new HSSFWorkbook(input);
- }
- Sheet sheet = wb.getSheetAt(0); //获得第一个表单
- Iterator<Row> rows = sheet.rowIterator(); //获得第一个表单的迭代器
- while (rows.hasNext()) {
- Row row = rows.next(); //获得行数据
- System.out.println("Row #" + row.getRowNum()); //获得行号从0开始
- Iterator<Cell> cells = row.cellIterator(); //获得第一行的迭代器
- while (cells.hasNext()) {
- Cell cell = cells.next();
- System.out.println("Cell #" + cell.getColumnIndex());
- switch (cell.getCellType()) { //根据cell中的类型来输出数据
- case NUMERIC:
- System.out.println(cell.getNumericCellValue());
- break;
- case STRING:
- System.out.println(cell.getStringCellValue());
- break;
- case BOOLEAN:
- System.out.println(cell.getBooleanCellValue());
- break;
- case FORMULA:
- System.out.println(cell.getCellFormula());
- break;
- default:
- System.out.println("unsuported sell type======="+cell.getCellType());
- break;
- }
- }
- }
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
|