diff --git a/README.md b/README.md index 16265e5..85d4de2 100644 --- a/README.md +++ b/README.md @@ -62,11 +62,11 @@ select 1 as a; # 数据库配置文件 -在当前目录下, 文件名称为: `databases.json`. 首次运行时会自动生成这个文件的默认内容, 默认自带一个 [h2](http://www.h2database.com/html/commands.html) 内存数据库, 名称为 `h2`, 可以做简单的测试和使用. +在当前目录下, 文件名称为: `databases.json`. 首次运行时会自动生成这个文件的默认内容, 默认自带一个 [h2](http://www.h2database.com/html/commands.html) 内存数据库, 名称为 `h2`, 可以做简单的测试和使用. 推荐自己配置一个mysql数据库使用. # SQL文件结构和语法定义 -文件后缀建议为sql, 以让文本编辑器支持sql语法的高亮显示. +文件后缀建议为sql, 以让你的文本编辑器支持sql语法的高亮显示. ## `# import` 导入一个xls, xlsx或csv文件 @@ -115,7 +115,7 @@ from test_table temp; ## 在SQL中可以使用 `$xxx` 的方式来引用之前的结果集 -注意: 一定要在结果集后面加一个自己的自定义名称, 结果集是以一个sub query的方式运行的, sql标准要求一定要指定一个别名的. +注意: 一定要在结果集后面加一个自己的自定义名称, 结果集是以一个子查询(或临时表)的方式运行的, sql标准要求子查询一定要指定一个别名. ```sql # import /Users/xxx/Downloads/xxx.xlsx @@ -189,6 +189,18 @@ from test_table2 ; ``` -## 关于空值null的导出显示控制 +## 空值null的导出显示控制 -默认情况下, 值为null会在导出时候显示成空字符串. 可以使用 `# export nulls` 来指定在导出文件的时候, null被导出为``, 这样可以看出来具体哪个是null值, 区分与空字符串. 然后, 后续可以使用 `# no export nulls` 来恢复默认行为, 即null被导出为空白, 和空字符串显示一样. \ No newline at end of file +默认情况下, 值为null会在导出时候显示成空字符串. 可以使用`# exportnulls`来指定在导出文件的时候, null被导出为``, 这样可以看出来具体哪个是null值, 与空字符串作区分. 可以使用`# -exportnulls`来恢复默认行为, 即null被导出为空白, 和空字符串显示一样. + +## 导出xlsx格式 + +使用`# exportxlsx`设置xlsx导出格式, 使用`# -exportxlsx`关闭xlsx导出格式. 默认: 关闭xlsx导出格式, 即导出格式为csv. + +## 临时表模式 + +默认情况下, 如果一个sql里引用了结果集, 结果集会以子查询的方式嵌入到sql中. 如果结果集数据量很大, 会导致子查询的sql很大, 从而导致超出java里String的最大容量, 或者超出mysql库的最大sql长度. + +使用临时表模式, 可以预先把结果集的数据导入到临时表中, 然后sql中直接从临时表查询结果集, 这样sql就比较短. + +使用`# temptables`打开临时表模式, 使用`# -temptables`关闭临时表模式. 默认: 关闭临时表模式. \ No newline at end of file diff --git a/note.txt b/note.txt index 413a9a7..e0afaca 100644 --- a/note.txt +++ b/note.txt @@ -1 +1,8 @@ 待开发功能: + 针对常见的错误, 直接在控制台显示具体的错误, 不需要打印调用栈 + 运行输出: 控制台+文件输出. + 子查询模式下, 检查子查询的长度(只有第一个select才需要指定列名称, 后续select不需要执行列名称) + +代码重构: + Sql, 根据不同的语句类型, 拆分成不同的子类. + 使用实例化的方式来调用工具类, 防止方法参数过多的问题. diff --git a/pom.xml b/pom.xml index 2abe6f3..1ebeda8 100644 --- a/pom.xml +++ b/pom.xml @@ -75,9 +75,9 @@ - org.apache.poi - poi - 3.10-FINAL + org.apache.commons + commons-collections4 + 4.4 @@ -89,13 +89,12 @@ org.apache.poi poi-ooxml - 3.10-FINAL + 5.2.2 - org.apache.poi - poi-ooxml-schemas - 3.10-FINAL + poi + 5.2.2 diff --git a/src/main/java/com/zwc/sqldataprocessor/ExportExecutor.java b/src/main/java/com/zwc/sqldataprocessor/ExportExecutor.java index d3e4841..2961fed 100644 --- a/src/main/java/com/zwc/sqldataprocessor/ExportExecutor.java +++ b/src/main/java/com/zwc/sqldataprocessor/ExportExecutor.java @@ -2,21 +2,23 @@ import com.zwc.sqldataprocessor.entity.DataList; import com.zwc.sqldataprocessor.exporter.CsvExporter; +import com.zwc.sqldataprocessor.exporter.Exporter; +import com.zwc.sqldataprocessor.exporter.XlsxExporter; public class ExportExecutor { - public static String export(String resultName, DataList table, String path, boolean exportNulls) { + public static String export(String resultName, DataList table, String path, boolean exportNulls, boolean exportXlsx) { // 执行导出 - CsvExporter exporter = new CsvExporter(); + Exporter exporter = exportXlsx ? new XlsxExporter() : new CsvExporter(); byte[] bytes = exporter.export(table, exportNulls); // 写入导出文件 if (path == null) { - path = String.format("./%s.csv", resultName); + path = String.format("./%s.%s", resultName, exporter.getExtension()); path = FileHelper.writeOutputFile(path, bytes); return path; } else if (!path.contains("/") && !path.contains("\\")) { - path = String.format("./%s.csv", path); + path = String.format("./%s.%s", path, exporter.getExtension()); path = FileHelper.writeOutputFile(path, bytes); return path; } diff --git a/src/main/java/com/zwc/sqldataprocessor/SqlExecutor.java b/src/main/java/com/zwc/sqldataprocessor/SqlExecutor.java index 46d2bbe..ddd9bb1 100644 --- a/src/main/java/com/zwc/sqldataprocessor/SqlExecutor.java +++ b/src/main/java/com/zwc/sqldataprocessor/SqlExecutor.java @@ -6,8 +6,10 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import com.zwc.sqldataprocessor.entity.DataList; import com.zwc.sqldataprocessor.entity.DataList.ColumnType; @@ -15,8 +17,14 @@ public class SqlExecutor { - public static DataList exec(String sql, String databaseName, Map tables) { - String rawSql = renderSql(sql, tables, databaseName); + public static DataList exec(String sql, String databaseName, Map tables, boolean useTempTables) { + String rawSql = renderSql(sql, tables, databaseName, useTempTables); + + // 解除group_concat的长度限制 + if (DatabaseConfigLoader.isMySql(databaseName)) { + execRawSql("SET SESSION group_concat_max_len = 1000000;", databaseName); + } + return execRawSql(rawSql, databaseName); } @@ -28,13 +36,6 @@ public static DataList execRawSql(String sql, String databaseName) { Connection conn = DatabaseConfigLoader.getConn(databaseName); - // 解除group_concat的长度限制 - if (DatabaseConfigLoader.isMySql(databaseName)) { - try (Statement cmd = conn.createStatement()) { - cmd.execute("SET SESSION group_concat_max_len = 1000000;"); - } - } - try (Statement cmd = conn.createStatement()) { boolean hasResult = cmd.execute(sql); @@ -116,7 +117,8 @@ static DataList readResult(ResultSet resultSet) throws SQLException { return table; } - static String renderSql(String sql, Map tables, String databaseName) { + static String renderSql(String sql, Map tables, String databaseName, boolean useTempTables) { + Set createdTempTables = new HashSet<>(); StringBuilder sqlBuilder = new StringBuilder(); for (String sqlLine : sql.split("\n")) { @@ -143,20 +145,42 @@ static String renderSql(String sql, Map tables, String databas throw new RuntimeException("结果集$" + tableName + "不存在."); } - // 构建数据集sql语句 - StringBuilder builder = new StringBuilder(); - builder.append("(\n"); - String tableSelectSql; - if (DatabaseConfigLoader.isH2(databaseName)) { - tableSelectSql = renderSelectSqlForH2(table); - } else { - tableSelectSql = renderSelectSql(table); + String tableReplacement = ""; + if (useTempTables) { // 构建临时表 + String tempTableName = "_temp_" + tableName.replace("$", ""); + + if (!createdTempTables.contains(tempTableName)) { + String sqlFormat = "drop temporary table if exists %s;"; + if (DatabaseConfigLoader.isH2(databaseName)) { + sqlFormat = "drop table if exists %s;"; + } + execRawSql(String.format(sqlFormat, tempTableName), databaseName); + String createTempTableSql = renderCreateTempTableSql(table, tempTableName, databaseName); + execRawSql(createTempTableSql, databaseName); + + // 分批导入数据 + List dataLists = table.split(10000); + for (DataList dataList : dataLists) { + String dataInsertSql = "insert into " + tempTableName + " "; + dataInsertSql += renderSelectSql(dataList, databaseName); + execRawSql(dataInsertSql, databaseName); + } + + createdTempTables.add(tempTableName); + } + + tableReplacement = tempTableName + " "; + } else { // 构建数据集sql语句 + StringBuilder builder = new StringBuilder(); + builder.append("(\n"); + String tableSelectSql = renderSelectSql(table, databaseName); + builder.append(tableSelectSql); + builder.append(") "); + tableReplacement = builder.toString(); } - builder.append(tableSelectSql); - builder.append(") "); // 替换到原sql里 - sqlLine = sqlLine.replace("$" + tableName + " ", builder.toString()); + sqlLine = sqlLine.replace("$" + tableName + " ", tableReplacement); } sqlBuilder.append(sqlLine); @@ -166,6 +190,42 @@ static String renderSql(String sql, Map tables, String databas return sqlBuilder.toString(); } + static String renderCreateTempTableSql(DataList table, String tableName, String databaseName) { + StringBuilder builder = new StringBuilder(); + builder.append("create temporary table " + tableName + "("); + for (int index = 0; index < table.columns.size(); ++index) { + builder.append("`" + table.columns.get(index) + "` "); + + ColumnType columnType = table.columnTypes.get(index); + if (columnType == ColumnType.INT) { + builder.append("bigint"); + } else if (columnType == ColumnType.DECIMAL) { + builder.append("decimal"); + } else if (columnType == ColumnType.DATETIME) { + builder.append("datetime"); + } else { + builder.append("LONGTEXT"); + } + + if (index != table.columns.size() - 1) { + builder.append(","); + } + } + builder.append(") "); + if (DatabaseConfigLoader.isMySql(databaseName)) { + builder.append("collate utf8mb4_general_ci CHARACTER SET utf8mb4"); + } + return builder.toString(); + } + + static String renderSelectSql(DataList table, String databaseName) { + if (DatabaseConfigLoader.isH2(databaseName)) { + return renderSelectSqlForH2(table); + } else { + return renderSelectSql(table); + } + } + static String renderSelectSql(DataList table) { if (table.rows.size() <= 0) { return renderEmptySelectSql(table); diff --git a/src/main/java/com/zwc/sqldataprocessor/SqlFileExecutor.java b/src/main/java/com/zwc/sqldataprocessor/SqlFileExecutor.java index d3376e5..d33e78d 100644 --- a/src/main/java/com/zwc/sqldataprocessor/SqlFileExecutor.java +++ b/src/main/java/com/zwc/sqldataprocessor/SqlFileExecutor.java @@ -56,7 +56,7 @@ static void internalExec(String filePath, Consumer logPrinter) { if (sql.type == SqlType.SQL) { logPrinter.accept("SQL: " + sql.databaseName); logPrinter.accept(sql.sql); - dataList = SqlExecutor.exec(sql.sql, sql.databaseName, tables); + dataList = SqlExecutor.exec(sql.sql, sql.databaseName, tables, sql.useTempTables); lastResultName = sql.resultName != null ? sql.resultName : defaultResultName; tables.put(lastResultName, dataList); printSqlStatus(lastResultName, dataList, logPrinter, startTime); @@ -64,7 +64,7 @@ static void internalExec(String filePath, Consumer logPrinter) { // 导出 if (sql.type == SqlType.EXPORT || sql.type == SqlType.END) { - doExport(lastResultName, dataList, logPrinter, sql.fileName, sql.exportNulls); + doExport(lastResultName, dataList, logPrinter, sql.fileName, sql.exportNulls, sql.exportXlsx); // 提前结束 if (sql.type == SqlType.END) { @@ -75,10 +75,10 @@ static void internalExec(String filePath, Consumer logPrinter) { } } - static void doExport(String resultName, DataList dataList, Consumer logPrinter, String filePath, boolean exportNulls) { + static void doExport(String resultName, DataList dataList, Consumer logPrinter, String filePath, boolean exportNulls, boolean exportXlsx) { // 导出 logPrinter.accept("导出结果集: " + resultName); - String exportPath = ExportExecutor.export(resultName, dataList, filePath, exportNulls); + String exportPath = ExportExecutor.export(resultName, dataList, filePath, exportNulls, exportXlsx); exportPath = Paths.get(exportPath).toFile().getAbsolutePath(); logPrinter.accept("导出文件路径: " + exportPath); diff --git a/src/main/java/com/zwc/sqldataprocessor/SqlLoader.java b/src/main/java/com/zwc/sqldataprocessor/SqlLoader.java index dfbc7d4..9aecbdc 100644 --- a/src/main/java/com/zwc/sqldataprocessor/SqlLoader.java +++ b/src/main/java/com/zwc/sqldataprocessor/SqlLoader.java @@ -13,25 +13,48 @@ public static List loadSql(String filePath) { String fileContent = FileHelper.readFile(filePath); List sqlList = new ArrayList<>(); boolean exportNulls = false; + boolean exportXlsx = false; + boolean useTempTables = false; for (String line : fileContent.split("\n")) { if (line.startsWith("# ")) { line = line.trim(); + String lowerLine = line.toLowerCase(); - if (line.startsWith("# end")) { + if (lowerLine.equals("# end")) { Sql endSql = new Sql(); endSql.type = SqlType.END; sqlList.add(endSql); continue; } - if (line.startsWith("# no export nulls")) { + if (lowerLine.equals("# exportnulls")) { + exportNulls = true; + continue; + } + + if (lowerLine.equals("# -exportnulls")) { exportNulls = false; continue; } - if (line.startsWith("# export nulls")) { - exportNulls = true; + if (lowerLine.equals("# exportxlsx")) { + exportXlsx = true; + continue; + } + + if (lowerLine.equals("# -exportxlsx")) { + exportXlsx = false; + continue; + } + + if (lowerLine.equals("# temptables")) { + useTempTables = true; + continue; + } + + if (lowerLine.equals("# -temptables")) { + useTempTables = false; continue; } @@ -53,6 +76,7 @@ public static List loadSql(String filePath) { Sql exportSql = new Sql(); exportSql.type = SqlType.EXPORT; exportSql.exportNulls = exportNulls; + exportSql.exportXlsx = exportXlsx; String exportFilePath = line.replace("# export", "").trim(); if (!exportFilePath.equals("")) { exportSql.fileName = exportFilePath; @@ -71,6 +95,7 @@ public static List loadSql(String filePath) { sql.databaseName = databaseName; sql.sql = ""; sql.resultName = getResultName(line); + sql.useTempTables = useTempTables; sqlList.add(sql); continue; } @@ -92,6 +117,7 @@ public static List loadSql(String filePath) { Sql exportSql = new Sql(); exportSql.type = SqlType.EXPORT; exportSql.exportNulls = exportNulls; + exportSql.exportXlsx = exportXlsx; sqlList.add(exportSql); } diff --git a/src/main/java/com/zwc/sqldataprocessor/entity/DataList.java b/src/main/java/com/zwc/sqldataprocessor/entity/DataList.java index f5ba1bf..3485784 100644 --- a/src/main/java/com/zwc/sqldataprocessor/entity/DataList.java +++ b/src/main/java/com/zwc/sqldataprocessor/entity/DataList.java @@ -1,8 +1,12 @@ package com.zwc.sqldataprocessor.entity; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import org.apache.commons.collections4.ListUtils; +import org.apache.poi.ss.formula.functions.T; + public class DataList { public List columns; @@ -14,4 +18,21 @@ public static enum ColumnType { TEXT } public List> rows = new ArrayList<>(); + + public List split(int maxRowCount) { + if (rows.size() <= maxRowCount) { + return Collections.singletonList(this); + } + + List>> partitions = ListUtils.partition(rows, maxRowCount); + List resultList = new ArrayList<>(); + for (List> partition : partitions) { + DataList dataList = new DataList(); + dataList.columns = columns; + dataList.columnTypes = columnTypes; + dataList.rows = partition; + resultList.add(dataList); + } + return resultList; + } } diff --git a/src/main/java/com/zwc/sqldataprocessor/entity/Sql.java b/src/main/java/com/zwc/sqldataprocessor/entity/Sql.java index 77bcd89..ae78f04 100644 --- a/src/main/java/com/zwc/sqldataprocessor/entity/Sql.java +++ b/src/main/java/com/zwc/sqldataprocessor/entity/Sql.java @@ -8,6 +8,8 @@ public class Sql { public String sheetName; public String resultName; public boolean exportNulls; + public boolean exportXlsx; + public boolean useTempTables; public enum SqlType { SQL, IMPORT, diff --git a/src/main/java/com/zwc/sqldataprocessor/exporter/CsvExporter.java b/src/main/java/com/zwc/sqldataprocessor/exporter/CsvExporter.java index 7332de6..6e7845e 100644 --- a/src/main/java/com/zwc/sqldataprocessor/exporter/CsvExporter.java +++ b/src/main/java/com/zwc/sqldataprocessor/exporter/CsvExporter.java @@ -8,7 +8,7 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; -public class CsvExporter { +public class CsvExporter implements Exporter { public byte[] export(DataList table, boolean exportNulls) { StringBuilder stringBuilder = new StringBuilder(); @@ -31,4 +31,9 @@ public byte[] export(DataList table, boolean exportNulls) { return stringBuilder.toString().getBytes(); } + @Override + public String getExtension() { + return "csv"; + } + } diff --git a/src/main/java/com/zwc/sqldataprocessor/exporter/Exporter.java b/src/main/java/com/zwc/sqldataprocessor/exporter/Exporter.java new file mode 100644 index 0000000..7146c49 --- /dev/null +++ b/src/main/java/com/zwc/sqldataprocessor/exporter/Exporter.java @@ -0,0 +1,8 @@ +package com.zwc.sqldataprocessor.exporter; + +import com.zwc.sqldataprocessor.entity.DataList; + +public interface Exporter { + byte[] export(DataList table, boolean exportNulls); + String getExtension(); +} diff --git a/src/main/java/com/zwc/sqldataprocessor/exporter/XlsxExporter.java b/src/main/java/com/zwc/sqldataprocessor/exporter/XlsxExporter.java new file mode 100644 index 0000000..e90a2ab --- /dev/null +++ b/src/main/java/com/zwc/sqldataprocessor/exporter/XlsxExporter.java @@ -0,0 +1,110 @@ +package com.zwc.sqldataprocessor.exporter; + +import java.io.ByteArrayOutputStream; +import java.nio.charset.Charset; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.function.Consumer; + +import com.zwc.sqldataprocessor.entity.DataList; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFFont; + +public class XlsxExporter implements Exporter { + + @Override + public byte[] export(DataList table, boolean exportNulls) { + LinkedHashMap tables = new LinkedHashMap<>(); + tables.put("sheet1", table); + return export(tables); + } + + @Override + public String getExtension() { + return "xlsx"; + } + + public byte[] export(LinkedHashMap tables) { + try (SXSSFWorkbook workbook = new SXSSFWorkbook(1000)) { + for (String sheetName : tables.keySet()) { + DataList table = tables.get(sheetName); + if (table.columns == null) { + continue; + } + SXSSFSheet sheet = workbook.createSheet(sheetName); + + // 写入表头 + XSSFCellStyle headStyle = (XSSFCellStyle) workbook.createCellStyle(); + headStyle.setAlignment(HorizontalAlignment.CENTER); + XSSFFont headFont = (XSSFFont )workbook.createFont(); + headFont.setBold(true); + headStyle.setFont(headFont); + int index = 0; + writeRow(sheet, index, table.columns, headStyle); + + // 写入行数据 + for (List row : table.rows) { + index++; + writeRow(sheet, index, row, null); + } + + // 检测列最大文字数 + int[] charCounts = new int[table.columns.size()]; + Consumer> detectCharCount = row -> { + for (int columnIndex = 0; columnIndex < row.size(); ++columnIndex) { + int charCount = row.get(columnIndex).getBytes(Charset.forName("GBK")).length; + charCounts[columnIndex] = Math.max(charCounts[columnIndex], charCount); + } + }; + detectCharCount.accept(table.columns); + for (List row : table.rows) { + detectCharCount.accept(row); + } + + // 设置列宽度 + for (int columnIndex = 0; columnIndex < table.columns.size(); ++columnIndex) { + // 限定宽度范围 + int charCount = Math.max(charCounts[columnIndex], 4); + charCount = Math.min(charCount, 80); + int width = (charCount + 4) * 220; + width = Math.min(width, 255*256); + sheet.setColumnWidth(columnIndex, width); + } + } + + // 生成二进制 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + workbook.write(outputStream); + return outputStream.toByteArray(); + + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + /** + * 写入行数据 + */ + void writeRow(SXSSFSheet sheet, int rowIndex, List values, CellStyle style) { + SXSSFRow row = sheet.createRow(rowIndex); + row.setHeight((short)400); + for (int columnIndex = 0; columnIndex < values.size(); ++columnIndex) { + SXSSFCell cell = row.createCell(columnIndex); + + // 写入数据 + cell.setCellValue(values.get(columnIndex)); + + // 设置样式 + if (style != null) { + cell.setCellStyle(style); + } + } + } +} diff --git a/src/main/java/com/zwc/sqldataprocessor/importer/XlsImporter.java b/src/main/java/com/zwc/sqldataprocessor/importer/XlsImporter.java index 32031f8..a91f3ab 100644 --- a/src/main/java/com/zwc/sqldataprocessor/importer/XlsImporter.java +++ b/src/main/java/com/zwc/sqldataprocessor/importer/XlsImporter.java @@ -13,8 +13,9 @@ import com.zwc.sqldataprocessor.entity.DataList; import com.zwc.sqldataprocessor.entity.DataList.ColumnType; import org.apache.commons.lang3.StringUtils; -import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; @@ -37,7 +38,7 @@ public DataList doImport(byte[] content, String sheetName) { if (isXlsx) { book = new XSSFWorkbook(new ByteArrayInputStream(content)); } else { - book = WorkbookFactory.create(new NPOIFSFileSystem(new ByteArrayInputStream(content))); + book = WorkbookFactory.create(new POIFSFileSystem(new ByteArrayInputStream(content))); } } catch (IOException e) { throw new RuntimeException(e); @@ -79,7 +80,7 @@ public DataList doImport(byte[] content, String sheetName) { } String value = cell.toString(); - if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { + if (cell.getCellType() == CellType.NUMERIC) { if (value.contains("E")) { double doubleValue = Double.parseDouble(value); NumberFormat numberFormat = NumberFormat.getInstance(); @@ -88,7 +89,7 @@ public DataList doImport(byte[] content, String sheetName) { } else if (value.endsWith(".0")) { value = value.substring(0, value.lastIndexOf(".")); } - } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) { + } else if (cell.getCellType() == CellType.FORMULA) { DecimalFormat decimalFormat = new DecimalFormat("0"); try { value = decimalFormat.format(cell.getNumericCellValue());