Java tutorial
/** * Copyright 2011-2016 Asakusa Framework Team. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.asakusafw.testtools.excel; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; import org.apache.hadoop.io.Writable; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Row; import com.asakusafw.modelgen.emitter.JavaName; import com.asakusafw.modelgen.source.MySqlDataType; import com.asakusafw.runtime.value.ByteOption; import com.asakusafw.runtime.value.DateOption; import com.asakusafw.runtime.value.DateTime; import com.asakusafw.runtime.value.DateTimeOption; import com.asakusafw.runtime.value.DecimalOption; import com.asakusafw.runtime.value.IntOption; import com.asakusafw.runtime.value.LongOption; import com.asakusafw.runtime.value.ShortOption; import com.asakusafw.runtime.value.StringOption; import com.asakusafw.runtime.value.ValueOption; import com.asakusafw.testtools.ColumnInfo; import com.asakusafw.testtools.ColumnMatchingCondition; import com.asakusafw.testtools.ConditionSheetItem; import com.asakusafw.testtools.Configuration; import com.asakusafw.testtools.Constants; import com.asakusafw.testtools.NullValueCondition; import com.asakusafw.testtools.RowMatchingCondition; import com.asakusafw.testtools.TestDataHolder; /** * Excel?? * @author shinichi.umegane */ public class ExcelUtils { // TODO MessageFormat.format? // TODO ?????? /** * Excel??long????? */ public static final long EXCEL_MAX_LONG = 999999999999999L; /** * Excel??long?????? */ public static final long EXCEL_MIN_LONG = -999999999999999L; private final String filename; private final String tablename; private final RowMatchingCondition rowMatchingCondition; private final HSSFWorkbook workbook; private final HSSFSheet inputDataSheet; private final HSSFSheet outputDataSheet; private final HSSFSheet testConditionSheet; /** * ? */ private final DateFormat dateFormat = new SimpleDateFormat(com.asakusafw.runtime.value.Date.FORMAT); /** * ? */ private final DateFormat dateTimeFormat = new SimpleDateFormat(DateTime.FORMAT); /** * ? */ private final List<ColumnInfo> columnInfos; /** * ?Excel???? * @param filename Excel??? * @throws IOException Excel??????? */ public ExcelUtils(String filename) throws IOException { this.filename = filename; InputStream is = new FileInputStream(filename); workbook = new HSSFWorkbook(is); inputDataSheet = workbook.getSheet(Constants.INPUT_DATA_SHEET_NAME); if (inputDataSheet == null) { throw new IOException( "Excel: " + filename + "??????"); } outputDataSheet = workbook.getSheet(Constants.OUTPUT_DATA_SHEET_NAME); if (outputDataSheet == null) { throw new IOException( "Excel: " + filename + "??????"); } testConditionSheet = workbook.getSheet(Constants.TEST_CONDITION_SHEET_NAME); if (testConditionSheet == null) { throw new IOException("Excel: " + filename + "???????"); } HSSFCell tableNameCell = getCell(testConditionSheet, ConditionSheetItem.TABLE_NAME.getRow(), ConditionSheetItem.TABLE_NAME.getCol() + 1); tablename = tableNameCell.getStringCellValue(); if (tablename == null || tablename.length() == 0) { throw new IOException( "Excel: " + filename + "?????????"); } HSSFCell rowMatchingConditionCell = getCell(testConditionSheet, ConditionSheetItem.ROW_MATCHING_CONDITION.getRow(), ConditionSheetItem.ROW_MATCHING_CONDITION.getCol() + 1); String rowMatchingConditionStr = rowMatchingConditionCell.getStringCellValue(); if (rowMatchingConditionStr == null || rowMatchingConditionStr.length() == 0) { throw new IOException("Excel: " + filename + "?????????"); } rowMatchingCondition = RowMatchingCondition.getConditonByJapanseName(rowMatchingConditionStr); if (rowMatchingCondition == null) { throw new IOException("Excel: " + filename + "????????????"); } columnInfos = createColumnInfos(); } /** * ??????? * @param sheet ? * @param row ? * @param col ?? * @return ?? */ private HSSFCell getCell(HSSFSheet sheet, HSSFRow row, int col) { HSSFCell cell = row.getCell(col); if (cell == null) { String fmt = "Excel???(), file = %s, sheet = %s, row = %d, col = %d"; String msg = String.format(fmt, filename, sheet.getSheetName(), row.getRowNum() + 1, col + 1); throw new InvalidExcelBookException(msg); } return cell; } /** * ???????? * @param sheet ? * @param rownum ?? * @param col ?? * @return ?? */ private HSSFCell getCell(HSSFSheet sheet, int rownum, int col) { HSSFRow row = sheet.getRow(rownum); if (isEmpty(row)) { String fmt = "Excel???(), file = %s, sheet = %s, row = %d"; String msg = String.format(fmt, filename, sheet.getSheetName(), rownum); throw new InvalidExcelBookException(msg); } HSSFCell cell = getCell(sheet, row, col); return cell; } /** * ?????????? * @param item ?? * @param row ? * @return ?? */ private HSSFCell getCell(ConditionSheetItem item, HSSFRow row) { int col = item.getCol(); HSSFCell cell = getCell(testConditionSheet, row, col); return cell; } /** * ?????????()?? * @param sheet ? * @param item ?? * @param row ? * @return ?? */ private String getStringCellValue(HSSFSheet sheet, ConditionSheetItem item, HSSFRow row) { HSSFCell cell = getCell(item, row); String ret; if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { double dval = cell.getNumericCellValue(); ret = Double.toString(dval); ret = ret.replaceAll("\\.0*$", ""); } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) { ret = ""; } else if (cell.getCellType() != Cell.CELL_TYPE_STRING) { String fmt = "Excel???????????? file = %s, sheet = %s, row = %d, col = %d"; int rownum = row.getRowNum() + 1; int col = item.getCol() + 1; String msg = String.format(fmt, filename, sheet.getSheetName(), rownum, col); throw new InvalidExcelBookException(msg); } else { ret = cell.getStringCellValue(); } return ret; } private Double getDubleCellValue(HSSFSheet sheet, ConditionSheetItem item, HSSFRow row) { HSSFCell cell = getCell(item, row); Double ret; if (cell.getCellType() == Cell.CELL_TYPE_STRING) { String str = cell.getStringCellValue(); if (str == null || str.length() == 0) { ret = null; } else { try { ret = Double.parseDouble(str); } catch (NumberFormatException e) { String fmt = "Excel???????????? file = %s, sheet = %s, row = %d, col = %d"; int rownum = row.getRowNum() + 1; int col = item.getCol() + 1; String msg = String.format(fmt, filename, sheet.getSheetName(), rownum, col); throw new InvalidExcelBookException(msg); } } } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) { ret = null; } else if (cell.getCellType() != Cell.CELL_TYPE_NUMERIC) { String fmt = "Excel???????????? file = %s, sheet = %s, row = %d, col = %d"; int rownum = row.getRowNum() + 1; int col = item.getCol() + 1; String msg = String.format(fmt, filename, sheet.getSheetName(), rownum, col); throw new InvalidExcelBookException(msg); } else { ret = cell.getNumericCellValue(); } return ret; } /** * ???????????? * @param item ?????? * @param row ? * @return ??? */ private String creaetExceptionMessage(ConditionSheetItem item, HSSFRow row) { String fmt = "Excel?????????? file = %s, = %d, = %s"; String msg = String.format(fmt, filename, row.getRowNum() + 1, item.getName()); return msg; } /** * ???? * @return * @throws IOException ?????? */ private List<ColumnInfo> createColumnInfos() throws IOException { List<ColumnInfo> list = new ArrayList<ColumnInfo>(); int rownum = ConditionSheetItem.NO.getRow(); for (;;) { rownum++; HSSFRow row = testConditionSheet.getRow(rownum); if (isEmpty(row)) { break; } // ?? String columnName = getStringCellValue(testConditionSheet, ConditionSheetItem.COLUMN_NAME, row); if (columnName.length() == 0) { String msg = creaetExceptionMessage(ConditionSheetItem.COLUMN_NAME, row); throw new InvalidExcelBookException(msg); } // String columnComment = getStringCellValue(testConditionSheet, ConditionSheetItem.COLUMN_COMMENT, row); // String dataTypeStr = getStringCellValue(testConditionSheet, ConditionSheetItem.DATA_TYPE, row); MySqlDataType dataType = MySqlDataType.getDataTypeByString(dataTypeStr); if (dataType == null) { String msg = creaetExceptionMessage(ConditionSheetItem.DATA_TYPE, row); throw new InvalidExcelBookException(msg); } // ??? Double dWidth = getDubleCellValue(testConditionSheet, ConditionSheetItem.WIDTH, row); Double dScale = getDubleCellValue(testConditionSheet, ConditionSheetItem.SCALE, row); long characterMaximumLength = 0; int numericPrecision = 0; int numericScale = 0; switch (dataType) { case CHAR: case VARCHAR: if (dWidth == null) { String msg = creaetExceptionMessage(ConditionSheetItem.WIDTH, row); throw new InvalidExcelBookException(msg); } characterMaximumLength = dWidth.longValue(); break; case DECIMAL: if (dWidth == null) { String msg = creaetExceptionMessage(ConditionSheetItem.WIDTH, row); throw new InvalidExcelBookException(msg); } numericPrecision = dWidth.intValue(); if (dScale == null) { String msg = creaetExceptionMessage(ConditionSheetItem.SCALE, row); throw new InvalidExcelBookException(msg); } numericScale = dScale.intValue(); break; default: // ??????????????? break; } // String keyStr = getStringCellValue(testConditionSheet, ConditionSheetItem.KEY_FLAG, row); boolean key = true; if (keyStr.trim().length() == 0) { key = false; } // NULL? String nullableStr = getStringCellValue(testConditionSheet, ConditionSheetItem.NULLABLE, row); boolean nullable = true; if (nullableStr.trim().length() == 0) { nullable = false; } // ? String columnMatchingConditionStr = getStringCellValue(testConditionSheet, ConditionSheetItem.MATCHING_CONDITION, row); ColumnMatchingCondition columnMatchingCondition = ColumnMatchingCondition .getConditonByJapanseName(columnMatchingConditionStr); if (columnMatchingCondition == null) { String msg = creaetExceptionMessage(ConditionSheetItem.MATCHING_CONDITION, row); throw new InvalidExcelBookException(msg); } // NULL?? String nullValueConditionStr = getStringCellValue(testConditionSheet, ConditionSheetItem.NULL_VALUE_CONDITION, row); NullValueCondition nullValueCondition = NullValueCondition .getConditonByJapanseName(nullValueConditionStr); if (nullValueCondition == null) { String msg = creaetExceptionMessage(ConditionSheetItem.NULL_VALUE_CONDITION, row); throw new InvalidExcelBookException(msg); } ColumnInfo info = new ColumnInfo(tablename, columnName, columnComment, dataType, characterMaximumLength, numericPrecision, numericScale, nullable, key, columnMatchingCondition, nullValueCondition); list.add(info); } return list; } /** * ????? * @return ? */ public Class<? extends Writable> getModelClass() { Configuration conf = Configuration.getInstance(); String pkgName = conf.getModelPackage(); String simpleName = JavaName.of(tablename).toTypeName(); Class<? extends Writable> cl; cl = findModelClass(pkgName, null, simpleName); if (cl != null) { return cl; } cl = findModelClass(pkgName, com.asakusafw.modelgen.Constants.SOURCE_TABLE, simpleName); if (cl != null) { return cl; } cl = findModelClass(pkgName, com.asakusafw.modelgen.Constants.SOURCE_VIEW, simpleName); if (cl != null) { return cl; } throw new RuntimeException(new ClassNotFoundException(buildModelClassName(pkgName, null, simpleName))); } private Class<? extends Writable> findModelClass(String pkgName, String sourceOrNull, String simpleName) { assert pkgName != null; assert simpleName != null; String qualifiedName = buildModelClassName(pkgName, sourceOrNull, simpleName); Class<? extends Writable> cl; try { cl = Class.forName(qualifiedName).asSubclass(Writable.class); } catch (ClassNotFoundException e) { return null; } return cl; } private String buildModelClassName(String pkgName, String sourceOrNull, String simpleName) { assert pkgName != null; assert simpleName != null; StringBuilder modelClassName = new StringBuilder(); modelClassName.append(pkgName); modelClassName.append('.'); if (sourceOrNull != null) { modelClassName.append(sourceOrNull); modelClassName.append('.'); } modelClassName.append(com.asakusafw.modelgen.Constants.CATEGORY_MODEL); modelClassName.append('.'); modelClassName.append(simpleName); String qualifiedName = modelClassName.toString(); return qualifiedName; } /** * ?????? * @param sheet ????? * @return ? */ private List<Writable> createDatalList(HSSFSheet sheet) { List<Writable> list = new ArrayList<Writable>(); Class<?> modelClass = getModelClass(); int rownum = 0; // 0?????? // 1??? for (;;) { rownum++; HSSFRow row = sheet.getRow(rownum); if (isEmpty(row)) { break; } Writable model; try { model = (Writable) modelClass.newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } for (int col = 0; col < columnInfos.size(); col++) { HSSFCell cell = row.getCell(col, Row.CREATE_NULL_AS_BLANK); MySqlDataType type = columnInfos.get(col).getDataType(); ValueOption<?> vo; switch (type) { case CHAR: case VARCHAR: vo = getStringOption(cell); break; case DATE: vo = getDateOption(cell); break; case DATETIME: case TIMESTAMP: vo = getDateTimeOption(cell); break; case DECIMAL: vo = getDecimalOption(cell); break; case TINY_INT: vo = getByteOption(cell); break; case SMALL_INT: vo = getShortOption(cell); break; case INT: vo = getIntOption(cell); break; case LONG: vo = getLongOption(cell); break; default: throw new RuntimeException("Unsupported data type: " + type); } try { String setterName = columnInfos.get(col).getSetterName(); Method setter = model.getClass().getMethod(setterName, vo.getClass()); setter.invoke(model, vo); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } list.add(model); } return list; } /** * Returns {@code true} iff the specified row does not exist or has only blank cells. * @param row the target row * @return {@code true} if is empty */ private boolean isEmpty(HSSFRow row) { if (row == null) { return true; } for (Iterator<Cell> iter = row.cellIterator(); iter.hasNext();) { if (iter.next().getCellType() != Cell.CELL_TYPE_BLANK) { return false; } } return true; } /** * ?ByteOption?? * @param cell ? * @return ? */ private ByteOption getByteOption(HSSFCell cell) { Long l = getLong(cell); ByteOption op = new ByteOption(); if (l == null) { op.setNull(); } else { if (l < Byte.MIN_VALUE || Byte.MAX_VALUE < l) { String msg = createExceptionMsg(cell, "????(" + l + ")"); throw new NumberFormatException(msg); } op.modify(l.byteValue()); } return op; } /** * ?ShortOption?? * @param cell ? * @return ? */ private ShortOption getShortOption(HSSFCell cell) { Long l = getLong(cell); ShortOption op = new ShortOption(); if (l == null) { op.setNull(); } else { if (l < Short.MIN_VALUE || Short.MAX_VALUE < l) { String msg = createExceptionMsg(cell, "????(" + l + ")"); throw new NumberFormatException(msg); } op.modify(l.shortValue()); } return op; } /** * ?IntOption?? * @param cell ? * @return ? */ private IntOption getIntOption(HSSFCell cell) { Long l = getLong(cell); IntOption op = new IntOption(); if (l == null) { op.setNull(); } else { if (l < Integer.MIN_VALUE || Integer.MAX_VALUE < l) { String msg = createExceptionMsg(cell, "????(" + l + ")"); throw new NumberFormatException(msg); } op.modify(l.intValue()); } return op; } /** * ?LongOption?? * @param cell ? * @return ? */ private LongOption getLongOption(HSSFCell cell) { Long l = getLong(cell); LongOption op = new LongOption(); if (l == null) { op.setNull(); } else { op.modify(l); } return op; } /** * ?DateOption?? * @param cell ? * @return ? */ private DateOption getDateOption(HSSFCell cell) { Date date = getDate(cell); DateOption op = new DateOption(); if (date == null) { op.setNull(); } else { Calendar cal = Calendar.getInstance(); cal.setTime(date); int y = cal.get(Calendar.YEAR); int m = cal.get(Calendar.MONTH); int d = cal.get(Calendar.DAY_OF_MONTH); int h = cal.get(Calendar.HOUR_OF_DAY); int min = cal.get(Calendar.MINUTE); int s = cal.get(Calendar.SECOND); if (h != 0 || min != 0 || s != 0) { String msg = createExceptionMsg(cell, "?0???????????"); throw new CellTypeMismatchException(msg); } int days = com.asakusafw.runtime.value.DateUtil.getDayFromDate(y, m + 1, d); op.modify(days); } return op; } /** * ?DateTimeOption?? * @param cell ? * @return ? */ private DateTimeOption getDateTimeOption(HSSFCell cell) { Date date = getDate(cell); DateTimeOption op = new DateTimeOption(); if (date == null) { op.setNull(); } else { Calendar cal = Calendar.getInstance(); cal.setTime(date); int y = cal.get(Calendar.YEAR); int m = cal.get(Calendar.MONTH); int d = cal.get(Calendar.DAY_OF_MONTH); int h = cal.get(Calendar.HOUR_OF_DAY); int min = cal.get(Calendar.MINUTE); int s = cal.get(Calendar.SECOND); int days = com.asakusafw.runtime.value.DateUtil.getDayFromDate(y, m + 1, d); int secs = com.asakusafw.runtime.value.DateUtil.getSecondFromTime(h, min, s); DateTime dt = new DateTime(); dt.setElapsedSeconds((long) days * 86400 + secs); op.modify(dt); } return op; } /** * ?StringOption?? * @param cell ? * @return ? */ private StringOption getStringOption(HSSFCell cell) { String str; switch (cell.getCellType()) { case Cell.CELL_TYPE_BLANK: str = null; break; case Cell.CELL_TYPE_BOOLEAN: if (cell.getBooleanCellValue()) { str = "1"; } else { str = "0"; } break; case Cell.CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { double d = cell.getNumericCellValue(); Date date = DateUtil.getJavaDate(d); str = dateTimeFormat.format(date); } else { double d = cell.getNumericCellValue(); str = Double.toString(d); str = str.replaceAll("\\.0*$", ""); } break; case Cell.CELL_TYPE_STRING: str = cell.getStringCellValue(); break; case Cell.CELL_TYPE_ERROR: case Cell.CELL_TYPE_FORMULA: default: String msg = createCellTypeMismatchExceptionMsg(cell, ""); throw new CellTypeMismatchException(msg); } StringOption stringOption = new StringOption(); stringOption.modify(str); return stringOption; } /** * ?DecimalOption?? * @param cell ? * @return ? */ private DecimalOption getDecimalOption(HSSFCell cell) { BigDecimal bigDecimal; switch (cell.getCellType()) { case Cell.CELL_TYPE_BLANK: bigDecimal = null; break; case Cell.CELL_TYPE_BOOLEAN: if (cell.getBooleanCellValue()) { bigDecimal = new BigDecimal(1); } else { bigDecimal = new BigDecimal(0); } break; case Cell.CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { String msg = createCellTypeMismatchExceptionMsg(cell, "DECIMAL"); throw new CellTypeMismatchException(msg); } else { double d = cell.getNumericCellValue(); if (d < EXCEL_MIN_LONG || EXCEL_MAX_LONG < d) { String msg = createExceptionMsg(cell, "????(" + d + ")"); throw new NumberFormatException(msg); } long l = (long) d; if (l != d) { String msg = createExceptionMsg(cell, "???DECIMAL???????"); throw new NumberFormatException(msg); } String str = Double.toString(d); str = str.replaceAll("\\.0*$", ""); bigDecimal = new BigDecimal(str); } break; case Cell.CELL_TYPE_STRING: String str = cell.getStringCellValue(); try { bigDecimal = new BigDecimal(str); } catch (NumberFormatException e) { String msg = createExceptionMsg(cell, "DECIMAL???????"); throw new NumberFormatException(msg); } break; case Cell.CELL_TYPE_ERROR: case Cell.CELL_TYPE_FORMULA: default: String msg = createCellTypeMismatchExceptionMsg(cell, "DECIMAL"); throw new CellTypeMismatchException(msg); } DecimalOption decimalOption = new DecimalOption(); decimalOption.modify(bigDecimal); return decimalOption; } /** * ?java.util.Data?? * @param cell ? * @return ? */ private Date getDate(HSSFCell cell) { Date date; switch (cell.getCellType()) { case Cell.CELL_TYPE_BLANK: date = null; break; case Cell.CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { double d = cell.getNumericCellValue(); date = DateUtil.getJavaDate(d); } else { String msg = createCellTypeMismatchExceptionMsg(cell, ""); throw new CellTypeMismatchException(msg); } break; case Cell.CELL_TYPE_STRING: String str = cell.getStringCellValue(); try { date = dateTimeFormat.parse(str); } catch (Exception e) { try { date = dateFormat.parse(str); } catch (Exception e2) { String msg = createCellTypeMismatchExceptionMsg(cell, ""); throw new CellTypeMismatchException(msg); } } break; case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_ERROR: case Cell.CELL_TYPE_FORMULA: default: String msg = createCellTypeMismatchExceptionMsg(cell, ""); throw new CellTypeMismatchException(msg); } return date; } /** * ?Long?? * @param cell ? * @return ? */ private Long getLong(HSSFCell cell) { Long l; switch (cell.getCellType()) { case Cell.CELL_TYPE_BLANK: l = null; break; case Cell.CELL_TYPE_BOOLEAN: if (cell.getBooleanCellValue()) { l = 1L; } else { l = 0L; } break; case Cell.CELL_TYPE_NUMERIC: double d = cell.getNumericCellValue(); if (d < EXCEL_MIN_LONG || EXCEL_MAX_LONG < d) { String msg = createExceptionMsg(cell, "????(" + d + ")"); throw new NumberFormatException(msg); } l = (long) d; if ((double) l != d) { String msg = createExceptionMsg(cell, "??????????"); throw new NumberFormatException(msg); } break; case Cell.CELL_TYPE_STRING: try { String str = cell.getStringCellValue(); l = Long.parseLong(str); } catch (Exception e) { String msg = createCellTypeMismatchExceptionMsg(cell, ""); throw new CellTypeMismatchException(msg); } break; case Cell.CELL_TYPE_ERROR: case Cell.CELL_TYPE_FORMULA: default: String msg = createCellTypeMismatchExceptionMsg(cell, ""); throw new CellTypeMismatchException(msg); } return l; } /** * ???????Exception?? * @param cell ? * @param msg * @return Exception? */ private String createExceptionMsg(HSSFCell cell, String msg) { int col = cell.getColumnIndex(); int rownum = cell.getRowIndex(); String sheetName = cell.getSheet().getSheetName(); String fmt = "%s, filename = %s, sheet = %s, row = %d, col = %d"; String ret = String.format(fmt, msg, filename, sheetName, rownum + 1, col + 1); return ret; } /** * ?????????Exception??? * @param cell * @param expect ?? * @return Exception? */ private String createCellTypeMismatchExceptionMsg(HSSFCell cell, String expect) { int col = cell.getColumnIndex(); int rownum = cell.getRowIndex(); String sheetName = cell.getSheet().getSheetName(); String actual; switch (cell.getCellType()) { case Cell.CELL_TYPE_BLANK: actual = ""; break; case Cell.CELL_TYPE_BOOLEAN: actual = "?"; break; case Cell.CELL_TYPE_ERROR: actual = ""; break; case Cell.CELL_TYPE_FORMULA: actual = "?"; break; case Cell.CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { actual = ""; } else { actual = ""; } break; case Cell.CELL_TYPE_STRING: actual = ""; break; default: actual = "?"; break; } String fmt = "Excel CELL??????????" + "expect = %s, actual = %s, filename = %s, sheet = %s, row = %d, col = %d"; String ret = String.format(fmt, expect, actual, filename, sheetName, rownum + 1, col + 1); return ret; } /** * ????? * @return ? */ public List<ColumnInfo> getColumnInfos() { return columnInfos; } /** * TestDataHolder?? * @return ??Excel??{@link TestDataHolder}? */ public TestDataHolder getTestDataHolder() { List<Writable> source = createDatalList(inputDataSheet); List<Writable> expect = createDatalList(outputDataSheet); Class<? extends Writable> modelClass = getModelClass(); return new TestDataHolder(source, expect, columnInfos, modelClass, rowMatchingCondition); } }