diff --git a/pom.xml b/pom.xml index ce22b0882cd2b7fbe4e881067cab864fc674fa16..80f9084c92f54fc48e9ea3aac2ec5a4a8a64bbe4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.magic-core excel-boot - 2.0 + 2.01 org.sonatype.oss diff --git a/src/main/java/com/excel/poi/ExcelBoot.java b/src/main/java/com/excel/poi/ExcelBoot.java index c29f43bed78720dc08468b4b092943e796a3744d..c9e3d4fa4c1340f5a81ae8feb4545b5578e34d97 100644 --- a/src/main/java/com/excel/poi/ExcelBoot.java +++ b/src/main/java/com/excel/poi/ExcelBoot.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; +import java.util.List; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; @@ -48,6 +49,7 @@ public class ExcelBoot { private Integer rowAccessWindowSize; private Integer recordCountPerSheet; private Boolean openAutoColumWidth; + private Integer maxContiguousBlankRowCount = Constant.MAX_ROW_COUNT_CONTIGUOUS_BLANK; /** * 导入构造器 @@ -56,7 +58,17 @@ public class ExcelBoot { * @param excelClass */ protected ExcelBoot(InputStream inputStream, Class excelClass) { - this(null, null, inputStream, null, excelClass, null, null, null, null); + this(null, null, inputStream, null, excelClass, null, null, null, null, null); + } + + /** + * 导入构造器 + * + * @param inputStream + * @param excelClass + */ + protected ExcelBoot(InputStream inputStream, Class excelClass, Integer maxContiguousBlankRowCount) { + this(null, null, inputStream, null, excelClass, null, null, null, null, maxContiguousBlankRowCount); } /** @@ -67,7 +79,7 @@ public class ExcelBoot { * @param excelClass */ protected ExcelBoot(OutputStream outputStream, String fileName, Class excelClass) { - this(null, outputStream, null, fileName, excelClass, Constant.DEFAULT_PAGE_SIZE, Constant.DEFAULT_ROW_ACCESS_WINDOW_SIZE, Constant.DEFAULT_RECORD_COUNT_PEER_SHEET, Constant.OPEN_AUTO_COLUM_WIDTH); + this(null, outputStream, null, fileName, excelClass, Constant.DEFAULT_PAGE_SIZE, Constant.DEFAULT_ROW_ACCESS_WINDOW_SIZE, Constant.DEFAULT_RECORD_COUNT_PEER_SHEET, Constant.OPEN_AUTO_COLUM_WIDTH, Constant.MAX_ROW_COUNT_CONTIGUOUS_BLANK); } /** @@ -78,7 +90,7 @@ public class ExcelBoot { * @param excelClass */ protected ExcelBoot(HttpServletResponse response, String fileName, Class excelClass) { - this(response, null, null, fileName, excelClass, Constant.DEFAULT_PAGE_SIZE, Constant.DEFAULT_ROW_ACCESS_WINDOW_SIZE, Constant.DEFAULT_RECORD_COUNT_PEER_SHEET, Constant.OPEN_AUTO_COLUM_WIDTH); + this(response, null, null, fileName, excelClass, Constant.DEFAULT_PAGE_SIZE, Constant.DEFAULT_ROW_ACCESS_WINDOW_SIZE, Constant.DEFAULT_RECORD_COUNT_PEER_SHEET, Constant.OPEN_AUTO_COLUM_WIDTH, Constant.MAX_ROW_COUNT_CONTIGUOUS_BLANK); } /** @@ -95,7 +107,7 @@ public class ExcelBoot { * @param openAutoColumWidth */ protected ExcelBoot(HttpServletResponse response, OutputStream outputStream, InputStream inputStream - , String fileName, Class excelClass, Integer pageSize, Integer rowAccessWindowSize, Integer recordCountPerSheet, Boolean openAutoColumWidth) { + , String fileName, Class excelClass, Integer pageSize, Integer rowAccessWindowSize, Integer recordCountPerSheet, Boolean openAutoColumWidth, Integer maxContiguousBlankRowCount) { this.httpServletResponse = response; this.outputStream = outputStream; this.inputStream = inputStream; @@ -105,6 +117,7 @@ public class ExcelBoot { this.rowAccessWindowSize = rowAccessWindowSize; this.recordCountPerSheet = recordCountPerSheet; this.openAutoColumWidth = openAutoColumWidth; + this.maxContiguousBlankRowCount = maxContiguousBlankRowCount; } /** @@ -146,7 +159,7 @@ public class ExcelBoot { public static ExcelBoot ExportBuilder(HttpServletResponse response, String fileName, Class excelClass, Integer pageSize, Integer rowAccessWindowSize, Integer recordCountPerSheet, Boolean openAutoColumWidth) { return new ExcelBoot(response, null, null - , fileName, excelClass, pageSize, rowAccessWindowSize, recordCountPerSheet, openAutoColumWidth); + , fileName, excelClass, pageSize, rowAccessWindowSize, recordCountPerSheet, openAutoColumWidth, null); } /** @@ -164,7 +177,7 @@ public class ExcelBoot { public static ExcelBoot ExportBuilder(OutputStream outputStream, String fileName, Class excelClass, Integer pageSize , Integer rowAccessWindowSize, Integer recordCountPerSheet, Boolean openAutoColumWidth) { return new ExcelBoot(null, outputStream, null - , fileName, excelClass, pageSize, rowAccessWindowSize, recordCountPerSheet, openAutoColumWidth); + , fileName, excelClass, pageSize, rowAccessWindowSize, recordCountPerSheet, openAutoColumWidth, null); } /** @@ -178,12 +191,22 @@ public class ExcelBoot { return new ExcelBoot(inputStreamm, clazz); } + /** + * 导入Excel文件数据 + * + * @param inputStreamm + * @param clazz + * @return + */ + public static ExcelBoot ImportBuilder(InputStream inputStreamm, Class clazz, int maxContiguousBlankRowCount) { + return new ExcelBoot(inputStreamm, clazz, maxContiguousBlankRowCount); + } + /** * 用于浏览器导出 * * @param param * @param exportFunction - * @param ExportFunction * @param * @param */ @@ -211,7 +234,6 @@ public class ExcelBoot { * 通过OutputStream导出excel文件,一般用于异步导出大Excel文件到本地路径 * * @param param - * @param ExportFunction * @param exportFunction * @param * @param @@ -237,7 +259,6 @@ public class ExcelBoot { * * @param param * @param exportFunction - * @param ExportFunction * @param * @param * @return @@ -263,7 +284,6 @@ public class ExcelBoot { * * @param param * @param exportFunction - * @param ExportFunction * @param * @param */ @@ -289,7 +309,6 @@ public class ExcelBoot { * 通过OutputStream分sheet导出excel文件,一般用于异步导出大Excel文件到本地路径 * * @param param - * @param ExportFunction * @param exportFunction * @param * @param @@ -316,7 +335,6 @@ public class ExcelBoot { * * @param param * @param exportFunction - * @param ExportFunction * @param * @param * @return @@ -340,7 +358,6 @@ public class ExcelBoot { /** * 导出-导入模板 * - * @param data * @throws Exception */ public void exportTemplate() { @@ -369,7 +386,6 @@ public class ExcelBoot { /** * 导入excel全部sheet * - * @param inputStream * @param importFunction * @throws OpenXML4JException * @throws SAXException @@ -393,6 +409,32 @@ public class ExcelBoot { } + /** + * 导入excel指定sheet + * + * @param importFunction + * @throws OpenXML4JException + * @throws SAXException + * @throws IOException + */ + public void importExcel(ImportFunction importFunction, List sheetIndexs) { + try { + if (importFunction == null) { + throw new ExcelBootException("excelReadHandler参数为空!"); + } + if (inputStream == null) { + throw new ExcelBootException("inputStream参数为空!"); + } + + ExcelEntity excelMapping = ExcelMappingFactory.loadImportExcelClass(excelClass); + ExcelReader excelReader = new ExcelReader(excelClass, excelMapping, 0, maxContiguousBlankRowCount, importFunction); + excelReader.process(inputStream, sheetIndexs); + } catch (Exception e) { + throw new ExcelBootException(e); + } + + } + private SXSSFWorkbook commonSingleSheet(R param, ExportFunction exportFunction) throws Exception { verifyParams(); ExcelEntity excelMapping = ExcelMappingFactory.loadExportExcelClass(excelClass, fileName); diff --git a/src/main/java/com/excel/poi/annotation/ImportField.java b/src/main/java/com/excel/poi/annotation/ImportField.java index a23d60bcbed245cfac819c715fbf444da5bdc935..47c346ed07bc3df49bb35f296b44be8cdcf95ab4 100644 --- a/src/main/java/com/excel/poi/annotation/ImportField.java +++ b/src/main/java/com/excel/poi/annotation/ImportField.java @@ -68,4 +68,16 @@ public @interface ImportField { * @return */ int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * excel列序号 从0开始 优先取序号,无序号则取序号名,前述情况外取类字段申明顺序 默认:-1 + * @return + */ + int excelColumnIndex() default -1; + + /** + * excel列序号名称,即excel显示的列名 从A开始 默认:NONE + * @return + */ + String excelColumnIndexName() default "NONE"; } diff --git a/src/main/java/com/excel/poi/common/Constant.java b/src/main/java/com/excel/poi/common/Constant.java index 6c177bf503824465dece7745179cbf2c9d9ac02b..2be114a859edec95e17cd4f796a20b03812ba033 100644 --- a/src/main/java/com/excel/poi/common/Constant.java +++ b/src/main/java/com/excel/poi/common/Constant.java @@ -47,4 +47,5 @@ public final class Constant { public static final int CHINESES_ATUO_SIZE_COLUMN_WIDTH_MIN = 15; public static final int MAX_RECORD_COUNT_PEER_SHEET = 1000000; + public static final int MAX_ROW_COUNT_CONTIGUOUS_BLANK = 0; } diff --git a/src/main/java/com/excel/poi/entity/ExcelPropertyEntity.java b/src/main/java/com/excel/poi/entity/ExcelPropertyEntity.java index 8b0ae1a8f1945d2fec132bd724efff0258cca060..f251a301be265fe353b975d32ab15a98e7520247 100644 --- a/src/main/java/com/excel/poi/entity/ExcelPropertyEntity.java +++ b/src/main/java/com/excel/poi/entity/ExcelPropertyEntity.java @@ -79,4 +79,10 @@ public class ExcelPropertyEntity { * @return 是否必填 */ private Boolean required; + + /** + * excel列序号 从0开始 默认:0 + * @return + */ + private int excelColumnIndex; } diff --git a/src/main/java/com/excel/poi/excel/ExcelReader.java b/src/main/java/com/excel/poi/excel/ExcelReader.java index 83c1fe58c379d4d04b42ec745effb53eb831c671..627b7bda68927c88fef400c220416a7ee6ae94fa 100644 --- a/src/main/java/com/excel/poi/excel/ExcelReader.java +++ b/src/main/java/com/excel/poi/excel/ExcelReader.java @@ -32,11 +32,10 @@ import java.io.InputStream; import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.ParseException; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; +import java.util.*; import java.util.concurrent.ExecutionException; + +import com.excel.poi.utils.ExcelUtils; import lombok.extern.slf4j.Slf4j; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; @@ -55,6 +54,8 @@ import org.xml.sax.helpers.XMLReaderFactory; */ @Slf4j public class ExcelReader extends DefaultHandler { + private Integer maxContiguousBlankRowCount = 0; + private Integer contiguousBlankRowCount = 0; private Integer currentSheetIndex = -1; private Integer currentRowIndex = 0; private Integer excelCurrentCellIndex = 0; @@ -68,7 +69,7 @@ public class ExcelReader extends DefaultHandler { private ExcelEntity excelMapping; private ImportFunction importFunction; private Class excelClass; - private List cellsOnRow = new ArrayList(); + private Map cellsOnRow = new HashMap(); private Integer beginReadRowIndex; private Integer dataCurrentCellIndex = -1; @@ -76,16 +77,29 @@ public class ExcelReader extends DefaultHandler { public ExcelReader(Class entityClass, ExcelEntity excelMapping, ImportFunction importFunction) { - this(entityClass, excelMapping, 1, importFunction); + this(entityClass, excelMapping, 1, Constant.MAX_ROW_COUNT_CONTIGUOUS_BLANK, importFunction); + } + + public ExcelReader(Class entityClass, + ExcelEntity excelMapping, + Integer beginReadRowIndex, + ImportFunction importFunction) { + this.excelClass = entityClass; + this.excelMapping = excelMapping; + this.beginReadRowIndex = beginReadRowIndex; + this.maxContiguousBlankRowCount = Constant.MAX_ROW_COUNT_CONTIGUOUS_BLANK; + this.importFunction = importFunction; } public ExcelReader(Class entityClass, ExcelEntity excelMapping, Integer beginReadRowIndex, + Integer maxContiguousBlankRowCount, ImportFunction importFunction) { this.excelClass = entityClass; this.excelMapping = excelMapping; this.beginReadRowIndex = beginReadRowIndex; + this.maxContiguousBlankRowCount = maxContiguousBlankRowCount; this.importFunction = importFunction; } @@ -127,6 +141,44 @@ public class ExcelReader extends DefaultHandler { } } + public void process(InputStream in, List sheetIndexs) + throws IOException, OpenXML4JException, SAXException { + OPCPackage opcPackage = null; + InputStream sheet = null; + InputSource sheetSource; + try { + opcPackage = OPCPackage.open(in); + XSSFReader xssfReader = new XSSFReader(opcPackage); + XMLReader parser = this.fetchSheetParser(xssfReader.getSharedStringsTable()); + + for(Integer sheetIndex : sheetIndexs) { + contiguousBlankRowCount = 0; + currentRowIndex = 0; + currentSheetIndex = sheetIndex; + try { + sheet = xssfReader.getSheet("rId" + (currentSheetIndex + 1)); + sheetSource = new InputSource(sheet); + try { + log.info("开始读取第{}个Sheet!", currentSheetIndex + 1); + parser.parse(sheetSource); + } catch (AllEmptyRowException e) { + log.warn(e.getMessage()); + } catch (Exception e) { + throw new ExcelBootException(e, "第{}个Sheet,第{}行,第{}列,系统发生异常! ", currentSheetIndex + 1, currentRowIndex + 1, dataCurrentCellIndex + 1); + } + } finally { + if (sheet != null) { + sheet.close(); + } + } + } + } finally { + if (opcPackage != null) { + opcPackage.close(); + } + } + } + /** * 获取sharedStrings.xml文件的XMLReader对象 * @@ -190,29 +242,22 @@ public class ExcelReader extends DefaultHandler { int index = Integer.parseInt(currentCellValue); currentCellValue = new XSSFRichTextString(mSharedStringsTable.getEntryAt(index)).toString(); } - if (!currentCellLocation.equals(previousCellLocation) && currentRowIndex != 0) { + if (!currentCellLocation.equals(previousCellLocation)) { for (int i = 0; i < countNullCell(currentCellLocation, previousCellLocation); i++) { - cellsOnRow.add(excelCurrentCellIndex, ""); + cellsOnRow.put(excelCurrentCellIndex, ""); excelCurrentCellIndex++; } } - if (currentRowIndex != 0 || !"".equals(currentCellValue.trim())) { + if (!"".equals(currentCellValue.trim())) { String value = this.getCellValue(currentCellValue.trim()); - cellsOnRow.add(excelCurrentCellIndex, value); - excelCurrentCellIndex++; + cellsOnRow.put(excelCurrentCellIndex, value); } + excelCurrentCellIndex++; } else if (Constant.ROW.equals(name)) { - if (currentRowIndex == 0) { - endCellLocation = currentCellLocation; - int propertySize = excelMapping.getPropertyList().size(); - if (cellsOnRow.size() != propertySize) { - throw new ExcelBootException("Excel有效列数不等于标注注解的属性数量!Excel列数:{},标注注解的属性数量:{}", cellsOnRow.size(), propertySize); - } - } if (null != endCellLocation) { for (int i = 0; i <= countNullCell(endCellLocation, currentCellLocation); i++) { - cellsOnRow.add(excelCurrentCellIndex, ""); + cellsOnRow.put(excelCurrentCellIndex, ""); excelCurrentCellIndex++; } } @@ -238,7 +283,6 @@ public class ExcelReader extends DefaultHandler { * 根据c节点的s属性获取单元格样式,去styles.xml文件找相应样式 * * @param cellType xml中单元格格式属性 - * @param cellStyleStr xml中样式属性 */ private void setCellType(String cellType) { if ("inlineStr".equals(cellType)) { @@ -265,23 +309,45 @@ public class ExcelReader extends DefaultHandler { } } + private int getMaxColumnNumber() { + List propertyList = excelMapping.getPropertyList(); + int maxIndex = -1; + for (int i = 0; i < propertyList.size(); i++) { + if (propertyList.get(i).getExcelColumnIndex() > maxIndex) { + maxIndex = propertyList.get(i).getExcelColumnIndex(); + } + } + return maxIndex + 1; + } + private void assembleData() throws Exception { if (currentRowIndex >= beginReadRowIndex) { List propertyList = excelMapping.getPropertyList(); - for (int i = 0; i < propertyList.size() - cellsOnRow.size(); i++) { - cellsOnRow.add(i, ""); + for (int i = 0; i < getMaxColumnNumber(); i++) { + if(cellsOnRow.get(i) != null) { + continue; + } + cellsOnRow.put(i, ""); } if (isAllEmptyRowData()) { + ++contiguousBlankRowCount; + } else { + contiguousBlankRowCount = 0; + } + if (isAllEmptyRowData() && contiguousBlankRowCount > maxContiguousBlankRowCount) { throw new AllEmptyRowException("第{}行为空行,第{}个Sheet导入结束!", currentRowIndex + 1, currentSheetIndex + 1); } + if (isAllEmptyRowData()) { + return; + } Object entity = excelClass.newInstance(); ErrorEntity errorEntity = ErrorEntity.builder().build(); for (int i = 0; i < propertyList.size(); i++) { - dataCurrentCellIndex = i; - Object cellValue = cellsOnRow.get(i); + dataCurrentCellIndex = propertyList.get(i).getExcelColumnIndex(); + Object cellValue = cellsOnRow.get(propertyList.get(i).getExcelColumnIndex()); ExcelPropertyEntity property = propertyList.get(i); - errorEntity = checkCellValue(i, property, cellValue); + errorEntity = checkCellValue(propertyList.get(i).getExcelColumnIndex(), property, cellValue); if (errorEntity.getErrorMessage() != null) { break; } @@ -301,8 +367,8 @@ public class ExcelReader extends DefaultHandler { private boolean isAllEmptyRowData() { int emptyCellCount = 0; - for (Object cellData : cellsOnRow) { - if (StringUtil.isBlank(cellData)) { + for (Map.Entry cellData : cellsOnRow.entrySet()) { + if (StringUtil.isBlank(cellData.getValue())) { emptyCellCount++; } } @@ -387,8 +453,8 @@ public class ExcelReader extends DefaultHandler { String xfdA = refA.replaceAll("\\d+", ""); String xfdB = refB.replaceAll("\\d+", ""); - xfdA = fillChar(xfdA, 3, '@', true); - xfdB = fillChar(xfdB, 3, '@', true); + xfdA = ExcelUtils.fillChar(xfdA, 3, '@', true); + xfdB = ExcelUtils.fillChar(xfdB, 3, '@', true); char[] letterA = xfdA.toCharArray(); char[] letterB = xfdB.toCharArray(); @@ -396,27 +462,6 @@ public class ExcelReader extends DefaultHandler { return res - 1; } - private String fillChar(String str, int len, char let, boolean isPre) { - int lenA = str.length(); - if (lenA < len) { - if (isPre) { - StringBuilder strBuilder = new StringBuilder(str); - for (int i = 0; i < (len - lenA); i++) { - strBuilder.insert(0, let); - } - str = strBuilder.toString(); - } else { - StringBuilder strBuilder = new StringBuilder(str); - for (int i = 0; i < (len - lenA); i++) { - strBuilder.append(let); - } - str = strBuilder.toString(); - } - } - return str; - } - - /** * 单元格中的数据可能的数据类型 */ diff --git a/src/main/java/com/excel/poi/factory/ExcelMappingFactory.java b/src/main/java/com/excel/poi/factory/ExcelMappingFactory.java index 4d2cab74689e800bb3db6a49de2131ff69776cda..76324a2c95427c67219190d63729b31d0e93d417 100644 --- a/src/main/java/com/excel/poi/factory/ExcelMappingFactory.java +++ b/src/main/java/com/excel/poi/factory/ExcelMappingFactory.java @@ -16,6 +16,7 @@ */ package com.excel.poi.factory; +import com.excel.poi.utils.ExcelUtils; import com.excel.poi.annotation.ExportField; import com.excel.poi.annotation.ImportField; import com.excel.poi.entity.ExcelEntity; @@ -54,6 +55,7 @@ public class ExcelMappingFactory { .regexMessage(importField.regexMessage().trim()) .scale(importField.scale()) .roundingMode(importField.roundingMode()) + .excelColumnIndex(ExcelUtils.getExcelColumnIndex(importField.excelColumnIndex(), importField.excelColumnIndexName(), propertyList.size())) .build(); propertyList.add(excelPropertyEntity); } diff --git a/src/main/java/com/excel/poi/utils/ExcelUtils.java b/src/main/java/com/excel/poi/utils/ExcelUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..0eb97f24978b498aa94f6b4cd65a9b00489aa130 --- /dev/null +++ b/src/main/java/com/excel/poi/utils/ExcelUtils.java @@ -0,0 +1,60 @@ +package com.excel.poi.utils; + +import com.excel.poi.exception.ExcelBootException; + +import java.util.HashMap; +import java.util.Map; + +public class ExcelUtils { + + public final static Map CHAR_NUMBER = getChar2Number(); + private static Map getChar2Number() { + Map char2Number = new HashMap(); + char2Number.put('0', 0); + for(int i=0;i<26;i++) { + char2Number.put((char) (i+65), i+1); + } + return char2Number; + } + + + public static int getExcelColumnIndex(int columnIndex, String columnIndexName, int defaultIndex) { + if(columnIndex >= 0) { + return columnIndex; + } + if(null == columnIndexName || "".equals(columnIndexName) || !columnIndexName.trim().matches("^[a-zA-Z]{1,3}$")) { + return defaultIndex; + } + columnIndexName = columnIndexName.trim().toUpperCase(); + columnIndexName = fillChar(columnIndexName, 3, '0', true); + char[] columnIndexNameParts = columnIndexName.toCharArray(); + if(columnIndexNameParts[0] >= 'X' && columnIndexNameParts[1] >= 'F' && columnIndexNameParts[2] > 'D') { + throw new ExcelBootException("Excel 2007及之后版本列最大为XFD(16383),当前设置为" + columnIndexName); + } + return CHAR_NUMBER.get(columnIndexNameParts[0]) * 26 * 26 + + CHAR_NUMBER.get(columnIndexNameParts[1]) * 26 + + CHAR_NUMBER.get(columnIndexNameParts[2]) - + 1; + } + + public static String fillChar(String str, int len, char let, boolean isPre) { + int lenA = str.length(); + if (lenA < len) { + if (isPre) { + StringBuilder strBuilder = new StringBuilder(str); + for (int i = 0; i < (len - lenA); i++) { + strBuilder.insert(0, let); + } + str = strBuilder.toString(); + } else { + StringBuilder strBuilder = new StringBuilder(str); + for (int i = 0; i < (len - lenA); i++) { + strBuilder.append(let); + } + str = strBuilder.toString(); + } + } + return str; + } + +} diff --git a/src/test/java/com/excel/poi/test/ExcelVO.java b/src/test/java/com/excel/poi/test/ExcelVO.java new file mode 100644 index 0000000000000000000000000000000000000000..38106309d0cf394a6082c7540f61176305440b11 --- /dev/null +++ b/src/test/java/com/excel/poi/test/ExcelVO.java @@ -0,0 +1,67 @@ +package com.excel.poi.test; + +import com.excel.poi.annotation.ImportField; + +public class ExcelVO { + + @ImportField(regex = "65|65\\d{9}", regexMessage="非批号" , required = true, excelColumnIndex = 0) + private String col_1; + @ImportField(regex = "[\\s\\S]*", regexMessage="列2校验失败", required = true, excelColumnIndex = 2) + private String col_2; + @ImportField(regex = "((CF|cf|Cf|cF)\\d{4})|(\\u4e00\\u53e3\\u4ef7)", regexMessage="列3校验失败", required = true, excelColumnIndex = 4) + private String col_3; + @ImportField(regex = "\\d+(\\.\\d{1,2})?", regexMessage="金额格式不正确", required = true, excelColumnIndex = 5) + private String col_4; + @ImportField(regex = "[\\s\\S]*", regexMessage="列5校验失败", excelColumnIndex = 6) + private String col_5; + @ImportField(regex = "[\\s\\S]*", regexMessage="列6校验失败", excelColumnIndex = 7) + private String col_6; + + public String getCol_1() { + return col_1; + } + + public void setCol_1(String col_1) { + this.col_1 = col_1; + } + + public String getCol_2() { + return col_2; + } + + public void setCol_2(String col_2) { + this.col_2 = col_2; + } + + public String getCol_3() { + return col_3; + } + + public void setCol_3(String col_3) { + this.col_3 = col_3; + } + + public String getCol_4() { + return col_4; + } + + public void setCol_4(String col_4) { + this.col_4 = col_4; + } + + public String getCol_5() { + return col_5; + } + + public void setCol_5(String col_5) { + this.col_5 = col_5; + } + + public String getCol_6() { + return col_6; + } + + public void setCol_6(String col_6) { + this.col_6 = col_6; + } +} diff --git a/src/test/java/com/excel/poi/test/Test.java b/src/test/java/com/excel/poi/test/Test.java new file mode 100644 index 0000000000000000000000000000000000000000..87618cbad38ff7b6353ae8dd28504acba13d7e60 --- /dev/null +++ b/src/test/java/com/excel/poi/test/Test.java @@ -0,0 +1,50 @@ +package com.excel.poi.test; + +import com.excel.poi.ExcelBoot; +import com.excel.poi.entity.ErrorEntity; +import com.excel.poi.function.ImportFunction; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Test { + public static void main(String... args) throws FileNotFoundException { + + Map batchCounterMap = new HashMap(); + batchCounterMap.put("counter", 0); + batchCounterMap.put("bad", 0); + + final List batchCodes = new ArrayList(); + final StringBuffer error = new StringBuffer(); + ExcelBoot.ImportBuilder(new FileInputStream("C:\\TDDownload\\点价资源数据 (6) - 副本.xlsx"), ExcelVO.class) + .importExcel(new ImportFunction() { + + /** + * @param sheetIndex 当前执行的Sheet的索引, 从1开始 + * @param rowIndex 当前执行的行数, 从1开始 + * @param inEntity Excel行数据的实体 + */ + @Override + public void onProcess(int sheetIndex, int rowIndex, ExcelVO inEntity) { + //将读取到Excel中每一行的inEntity数据进行自定义处理 + //如果该行数据发生问题,将不会走本方法,而会走onError方法 + batchCodes.add(inEntity.getCol_1()); + } + + /** + * @param errorEntity 错误信息实体 + */ + @Override + public void onError(ErrorEntity errorEntity) { + //将每条数据非空和正则校验后的错误信息errorEntity进行自定义处理 + error.append(errorEntity.getRowIndex()+1).append("行数据处理错误,\r\n"); + } + }); + System.out.println(batchCodes); + System.out.println(error); + } +} diff --git a/src/test/java/com/excel/poi/test/Test2.java b/src/test/java/com/excel/poi/test/Test2.java new file mode 100644 index 0000000000000000000000000000000000000000..ad3bef4d0e26e35635a1f7afd8e4f7dea946fc91 --- /dev/null +++ b/src/test/java/com/excel/poi/test/Test2.java @@ -0,0 +1,54 @@ +package com.excel.poi.test; + +import com.excel.poi.ExcelBoot; +import com.excel.poi.entity.ErrorEntity; +import com.excel.poi.function.ImportFunction; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.*; + +public class Test2 { + public static void main(String... args) throws FileNotFoundException { + + Map batchCounterMap = new HashMap(); + batchCounterMap.put("counter", 0); + batchCounterMap.put("bad", 0); + + final List batchCodes = new ArrayList(); + final StringBuffer error = new StringBuffer(); + String f = "C:\\TDDownload\\点价资源数据 (6) - 副本.xlsx"; +// String f = "C:\\TDDownload\\点价资源数据 (6) - 副本 - 副本.xlsx"; + ExcelBoot.ImportBuilder(new FileInputStream(f), ExcelVO.class, 2) + .importExcel(new ImportFunction() { + + /** + * @param sheetIndex 当前执行的Sheet的索引, 从1开始 + * @param rowIndex 当前执行的行数, 从1开始 + * @param inEntity Excel行数据的实体 + */ + @Override + public void onProcess(int sheetIndex, int rowIndex, ExcelVO inEntity) { + //将读取到Excel中每一行的inEntity数据进行自定义处理 + //如果该行数据发生问题,将不会走本方法,而会走onError方法 + batchCodes.add(new StringBuffer(inEntity.getCol_1()).append("||") + .append(inEntity.getCol_2()).append("||") + .append(inEntity.getCol_3()).append("||") + .append(inEntity.getCol_4()).append("||") + .append(inEntity.getCol_5()).append("||") + .append(inEntity.getCol_6()).toString()); + } + + /** + * @param errorEntity 错误信息实体 + */ + @Override + public void onError(ErrorEntity errorEntity) { + //将每条数据非空和正则校验后的错误信息errorEntity进行自定义处理 + error.append(errorEntity.getRowIndex()).append("行数据处理错误,").append(errorEntity.getErrorMessage()).append("\r\n"); + } + }, new ArrayList(Arrays.asList(0))); + System.out.println(batchCodes); + System.out.println(error); + } +} diff --git a/src/test/java/com/excel/poi/utils/ExcelUtilsTest.java b/src/test/java/com/excel/poi/utils/ExcelUtilsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..47befaa96a0f625bfd25c975eb166686cb7e0699 --- /dev/null +++ b/src/test/java/com/excel/poi/utils/ExcelUtilsTest.java @@ -0,0 +1,67 @@ +package com.excel.poi.utils; + +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.FileOutputStream; +import java.io.IOException; + +public class ExcelUtilsTest { + + public static void main(String... args) throws IOException { + writeColXlsx(); + + System.out.println(ExcelUtils.getExcelColumnIndex(-1, "XFD", -9)); + + } + + public static void writeColXlsx() throws IOException { + Workbook workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet("列"); + Row rowChar = sheet.createRow(0); + Row rowIndex = sheet.createRow(1); + Row rowActualIndex = sheet.createRow(2); + int colIndex = 0; + String tmp = null; + for(int i=0;i<26;i++) { + tmp = null; + tmp = String.valueOf((char) (i+65)); + rowChar.createCell(colIndex).setCellValue(tmp); + rowIndex.createCell(colIndex).setCellValue(ExcelUtils.getExcelColumnIndex(-1, tmp, -3)); + rowActualIndex.createCell(colIndex).setCellValue(colIndex); + colIndex++; + } + for(int i=0;i<26;i++) { + for(int j=0;j<26;j++) { + tmp = null; + tmp = String.valueOf((char) (i+65)) + String.valueOf((char) (j+65)); + rowChar.createCell(colIndex).setCellValue(tmp); + rowIndex.createCell(colIndex).setCellValue(ExcelUtils.getExcelColumnIndex(-1, tmp, -3)); + rowActualIndex.createCell(colIndex).setCellValue(colIndex); + colIndex++; + } + } + for(int i=0;i<26;i++) { + for(int j=0;j<26;j++) { + for(int k=0;k<26;k++) { + if(colIndex >= 16384) { + break; + } + tmp = null; + tmp = String.valueOf((char) (i+65)) + String.valueOf((char) (j+65)) + String.valueOf((char) (k+65)); + rowChar.createCell(colIndex).setCellValue(tmp); + rowIndex.createCell(colIndex).setCellValue(ExcelUtils.getExcelColumnIndex(-1, tmp, -3)); + rowActualIndex.createCell(colIndex).setCellValue(colIndex); + colIndex++; + } + } + } + + FileOutputStream fos = new FileOutputStream("d:\\col.xlsx"); + workbook.write(fos); + workbook.close(); + fos.close(); + } +}