• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    使用SQL语言查询多个Excel表格的操作方法

    发布者: 涵韵 | 发布时间: 2025-6-18 09:14| 查看数: 73| 评论数: 0|帖子模式

    如何用SQL语言查询多个Excel表格

    没错,之前我也不知道SQL语言除了可以查询(本文只讨论查询语句)数据库,还可以查询Excel,或者说经过一定处理后,可以像查询数据库一样查询Excel。
    下面给出一个场景,假如你有几个(个数未知)Excel表格,你想在这些表格上实现SQL多表查询,该怎么办?
    像这样:
    学号姓名
    1054小姜
    1055小王
    1061小李
    1081王哥
    课程名称任课老师
    人工智能王老师
    数据库李老师
    运筹学张老师
    概率论郝老师
    学号课程名称分数
    1054人工智能90
    1055数据库91
    1061运筹学92
    1081概率论91
    1054运筹学89
    1055概率论91
    1061人工智能95
    1081数据库94
    大致思路如下:

    • 将所有要导入的Excel表放入一个.xlsx文件中,将各Sheet命名为表名,类似数据库的table名;
    • 利用pandas库读取.xlsx文件并创建为一个ExcelFile类;
    • 利用类中名为sheet_names的property获取其所有该文件所有的Sheet名;
    • 用locals和read_excel函数创建名为各sheet名,值为各sheet内容的局部变量;
    • 利用pandasql库中的sqldf来查询一个或多个dataframe,sqldf函数默认查询所有局部变量中的dataframe。
    利用pandasql库中的sqldf来查询一个或多个dataframe,sqldf函数默认查询所有局部变量中的dataframe。
    代码如下:
    1. import pandas as pd
    2. from pandasql import sqldf
    3. def dealwith_excel(excel_file,sql_query):
    4.     xls = pd.ExcelFile(excel_file)
    5.     sheet_names = xls.sheet_names #list type
    6.     # print(sheet_names)
    7.     for sheet_name in sheet_names:
    8.         locals()[sheet_name] = pd.read_excel(excel_file, sheet_name=sheet_name)
    9.     df_result = sqldf(sql_query)
    10.     return df_result
    复制代码
    最后返回的就是查询结果!
    扩展:

    如何使用sql查询excel内容


    1. 简介

    我们在前面的文章中提到了calcite支持csv和json文件的数据源适配, 其实就是将文件解析成表然后以文件夹为schema, 然后将生成的schema注册到
    1. RootSehema(RootSchema是所有数据源schema的parent,多个不同数据源schema可以挂在同一个RootSchema下)
    复制代码
    下, 最终使用calcite的特性进行sql的解析查询返回.
    但其实我们的数据文件一般使用excel进行存储,流转, 但很可惜, calcite本身没有excel的适配器, 但其实我们可以模仿
    1. calcite-file
    复制代码
    , 自己搞一个
    1. calcite-file-excel
    复制代码
    , 也可以熟悉calcite的工作原理.

    2. 实现思路

    因为excel有sheet的概念, 所以可以将一个excel解析成schema, 每个sheet解析成table, 实现步骤如下:

    • 实现
      1. SchemaFactory
      复制代码
      重写create方法: schema工厂 用于创建schema
    • 继承
      1. AbstractSchema
      复制代码
      : schema描述类 用于解析excel, 创建table(解析sheet)
    • 继承
      1. AbstractTable, ScannableTable
      复制代码
      : table描述类 提供字段信息和数据内容等(解析sheet data)

    3. Excel样例

    excel有两个sheet页, 分别是
    1. user_info
    复制代码
    1. role_info
    复制代码
    如下:


    ok, 万事具备.

    4. Maven
    1. <dependency>
    2.     <groupId>org.apache.poi</groupId>
    3.     <artifactId>poi-ooxml</artifactId>
    4.     <version>5.2.3</version>
    5. </dependency>
    6. <dependency>
    7.     <groupId>org.apache.poi</groupId>
    8.     <artifactId>poi</artifactId>
    9.     <version>5.2.3</version>
    10. </dependency>
    11. <dependency>
    12.     <groupId>org.apache.calcite</groupId>
    13.     <artifactId>calcite-core</artifactId>
    14.     <version>1.37.0</version>
    15. </dependency>
    复制代码
    5. 核心代码


    5.1 SchemaFactory
    1. package com.ldx.calcite.excel;
    2. import com.google.common.collect.Lists;
    3. import org.apache.calcite.schema.Schema;
    4. import org.apache.calcite.schema.SchemaFactory;
    5. import org.apache.calcite.schema.SchemaPlus;
    6. import org.apache.commons.lang3.ObjectUtils;
    7. import org.apache.commons.lang3.StringUtils;
    8. import java.io.File;
    9. import java.util.List;
    10. import java.util.Map;
    11. /**
    12. * schema factory
    13. */
    14. public class ExcelSchemaFactory implements SchemaFactory {
    15.     public final static ExcelSchemaFactory INSTANCE = new ExcelSchemaFactory();
    16.     private ExcelSchemaFactory(){}
    17.     @Override
    18.     public Schema create(SchemaPlus parentSchema, String name, Map<String, Object> operand) {
    19.         final Object filePath = operand.get("filePath");
    20.         if (ObjectUtils.isEmpty(filePath)) {
    21.             throw new NullPointerException("can not find excel file");
    22.         }
    23.         return this.create(filePath.toString());
    24.     }
    25.     public Schema create(String excelFilePath) {
    26.         if (StringUtils.isBlank(excelFilePath)) {
    27.             throw new NullPointerException("can not find excel file");
    28.         }
    29.         return this.create(new File(excelFilePath));
    30.     }
    31.     public Schema create(File excelFile) {
    32.         if (ObjectUtils.isEmpty(excelFile) || !excelFile.exists()) {
    33.             throw new NullPointerException("can not find excel file");
    34.         }
    35.         if (!excelFile.isFile() || !isExcelFile(excelFile)) {
    36.             throw new RuntimeException("can not find excel file: " + excelFile.getAbsolutePath());
    37.         }
    38.         return new ExcelSchema(excelFile);
    39.     }
    40.     protected List<String> supportedFileSuffix() {
    41.         return Lists.newArrayList("xls", "xlsx");
    42.     }
    43.     private boolean isExcelFile(File excelFile) {
    44.         if (ObjectUtils.isEmpty(excelFile)) {
    45.             return false;
    46.         }
    47.         final String name = excelFile.getName();
    48.         return StringUtils.endsWithAny(name, this.supportedFileSuffix().toArray(new String[0]));
    49.     }
    50. }
    复制代码
    schema中有多个重载的create方法用于方便的创建schema, 最终将excel file 交给
    1. ExcelSchema
    复制代码
    创建一个schema对象

    5.2 Schema
    1. package com.ldx.calcite.excel;
    2. import org.apache.calcite.schema.Table;
    3. import org.apache.calcite.schema.impl.AbstractSchema;
    4. import org.apache.commons.lang3.ObjectUtils;
    5. import org.apache.poi.ss.usermodel.Sheet;
    6. import org.apache.poi.ss.usermodel.Workbook;
    7. import org.apache.poi.ss.usermodel.WorkbookFactory;
    8. import org.testng.collections.Maps;
    9. import java.io.File;
    10. import java.util.Iterator;
    11. import java.util.Map;
    12. /**
    13. * schema
    14. */
    15. public class ExcelSchema extends AbstractSchema {
    16.     private final File excelFile;
    17.     private Map<String, Table> tableMap;
    18.     public ExcelSchema(File excelFile) {
    19.         this.excelFile = excelFile;
    20.     }
    21.     @Override
    22.     protected Map<String, Table> getTableMap() {
    23.         if (ObjectUtils.isEmpty(tableMap)) {
    24.             tableMap = createTableMap();
    25.         }
    26.         return tableMap;
    27.     }
    28.     private Map<String, Table> createTableMap() {
    29.         final Map<String, Table> result = Maps.newHashMap();
    30.         try (Workbook workbook = WorkbookFactory.create(excelFile)) {
    31.             final Iterator<Sheet> sheetIterator = workbook.sheetIterator();
    32.             while (sheetIterator.hasNext()) {
    33.                 final Sheet sheet = sheetIterator.next();
    34.                 final ExcelScannableTable excelScannableTable = new ExcelScannableTable(sheet, null);
    35.                 result.put(sheet.getSheetName(), excelScannableTable);
    36.             }
    37.         }
    38.         catch (Exception ignored) {}
    39.         return result;
    40.     }
    41. }
    复制代码
    schema类读取Excel file, 并循环读取sheet, 将每个sheet解析成
    1. ExcelScannableTable
    复制代码
    并存储

    5.3 Table
    1. package com.ldx.calcite.excel;
    2. import com.google.common.collect.Lists;
    3. import com.ldx.calcite.excel.enums.JavaFileTypeEnum;
    4. import org.apache.calcite.DataContext;
    5. import org.apache.calcite.adapter.java.JavaTypeFactory;
    6. import org.apache.calcite.linq4j.Enumerable;
    7. import org.apache.calcite.linq4j.Linq4j;
    8. import org.apache.calcite.rel.type.RelDataType;
    9. import org.apache.calcite.rel.type.RelDataTypeFactory;
    10. import org.apache.calcite.rel.type.RelProtoDataType;
    11. import org.apache.calcite.schema.ScannableTable;
    12. import org.apache.calcite.schema.impl.AbstractTable;
    13. import org.apache.calcite.sql.type.SqlTypeName;
    14. import org.apache.calcite.util.Pair;
    15. import org.apache.commons.lang3.ObjectUtils;
    16. import org.apache.poi.ss.usermodel.Cell;
    17. import org.apache.poi.ss.usermodel.Row;
    18. import org.apache.poi.ss.usermodel.Sheet;
    19. import org.checkerframework.checker.nullness.qual.Nullable;
    20. import java.util.List;
    21. /**
    22. * table
    23. */
    24. public class ExcelScannableTable extends AbstractTable implements ScannableTable {
    25.     private final RelProtoDataType protoRowType;
    26.     private final Sheet sheet;
    27.     private RelDataType rowType;
    28.     private List<JavaFileTypeEnum> fieldTypes;
    29.     private List<Object[]> rowDataList;
    30.     public ExcelScannableTable(Sheet sheet, RelProtoDataType protoRowType) {
    31.         this.protoRowType = protoRowType;
    32.         this.sheet = sheet;
    33.     }
    34.     @Override
    35.     public Enumerable<@Nullable Object[]> scan(DataContext root) {
    36.         JavaTypeFactory typeFactory = root.getTypeFactory();
    37.         final List<JavaFileTypeEnum> fieldTypes = this.getFieldTypes(typeFactory);
    38.         if (rowDataList == null) {
    39.             rowDataList = readExcelData(sheet, fieldTypes);
    40.         }
    41.         return Linq4j.asEnumerable(rowDataList);
    42.     }
    43.     @Override
    44.     public RelDataType getRowType(RelDataTypeFactory typeFactory) {
    45.         if (ObjectUtils.isNotEmpty(protoRowType)) {
    46.             return protoRowType.apply(typeFactory);
    47.         }
    48.         if (ObjectUtils.isEmpty(rowType)) {
    49.             rowType = deduceRowType((JavaTypeFactory) typeFactory, sheet, null);
    50.         }
    51.         return rowType;
    52.     }
    53.     public List<JavaFileTypeEnum> getFieldTypes(RelDataTypeFactory typeFactory) {
    54.         if (fieldTypes == null) {
    55.             fieldTypes = Lists.newArrayList();
    56.             deduceRowType((JavaTypeFactory) typeFactory, sheet, fieldTypes);
    57.         }
    58.         return fieldTypes;
    59.     }
    60.     private List<Object[]> readExcelData(Sheet sheet, List<JavaFileTypeEnum> fieldTypes) {
    61.         List<Object[]> rowDataList = Lists.newArrayList();
    62.         for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
    63.             Row row = sheet.getRow(rowIndex);
    64.             Object[] rowData = new Object[fieldTypes.size()];
    65.             for (int i = 0; i < row.getLastCellNum(); i++) {
    66.                 final JavaFileTypeEnum javaFileTypeEnum = fieldTypes.get(i);
    67.                 Cell cell = row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
    68.                 final Object cellValue = javaFileTypeEnum.getCellValue(cell);
    69.                 rowData[i] = cellValue;
    70.             }
    71.             rowDataList.add(rowData);
    72.         }
    73.         return rowDataList;
    74.     }
    75.     public static RelDataType deduceRowType(JavaTypeFactory typeFactory, Sheet sheet, List<JavaFileTypeEnum> fieldTypes) {
    76.         final List<String> names = Lists.newArrayList();
    77.         final List<RelDataType> types = Lists.newArrayList();
    78.         if (sheet != null) {
    79.             Row headerRow = sheet.getRow(0);
    80.             if (headerRow != null) {
    81.                 for (int i = 0; i < headerRow.getLastCellNum(); i++) {
    82.                     Cell cell = headerRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
    83.                     String[] columnInfo = cell
    84.                             .getStringCellValue()
    85.                             .split(":");
    86.                     String columnName = columnInfo[0].trim();
    87.                     String columnType = null;
    88.                     if (columnInfo.length == 2) {
    89.                         columnType = columnInfo[1].trim();
    90.                     }
    91.                     final JavaFileTypeEnum javaFileType = JavaFileTypeEnum
    92.                             .of(columnType)
    93.                             .orElse(JavaFileTypeEnum.UNKNOWN);
    94.                     final RelDataType sqlType = typeFactory.createSqlType(javaFileType.getSqlTypeName());
    95.                     names.add(columnName);
    96.                     types.add(sqlType);
    97.                     if (fieldTypes != null) {
    98.                         fieldTypes.add(javaFileType);
    99.                     }
    100.                 }
    101.             }
    102.         }
    103.         if (names.isEmpty()) {
    104.             names.add("line");
    105.             types.add(typeFactory.createSqlType(SqlTypeName.VARCHAR));
    106.         }
    107.         return typeFactory.createStructType(Pair.zip(names, types));
    108.     }
    109. }
    复制代码
    table类中其中有两个比较关键的方法
    1. scan
    复制代码
    : 扫描表内容, 我们这里将sheet页面的数据内容解析存储最后交给calcite
    1. getRowType
    复制代码
    : 获取字段信息, 我们这里默认使用第一条记录作为表头(row[0]) 并解析为字段信息, 字段规则跟csv一样
    1. name:string
    复制代码
    , 冒号前面的是字段key, 冒号后面的是字段类型, 如果未指定字段类型, 则解析为
    1. UNKNOWN
    复制代码
    , 后续
    1. JavaFileTypeEnum
    复制代码
    会进行类型推断, 最终在结果处理时calcite也会进行推断
    1. deduceRowType
    复制代码
    : 推断字段类型, 方法中使用
    1. JavaFileTypeEnum
    复制代码
    枚举类对java type & sql type & 字段值转化处理方法 进行管理

    5.4 ColumnTypeEnum
    1. package com.ldx.calcite.excel.enums;
    2. import lombok.Getter;
    3. import lombok.extern.slf4j.Slf4j;
    4. import org.apache.calcite.avatica.util.DateTimeUtils;
    5. import org.apache.calcite.sql.type.SqlTypeName;
    6. import org.apache.commons.lang3.ObjectUtils;
    7. import org.apache.commons.lang3.StringUtils;
    8. import org.apache.commons.lang3.time.FastDateFormat;
    9. import org.apache.poi.ss.usermodel.Cell;
    10. import org.apache.poi.ss.usermodel.DateUtil;
    11. import org.apache.poi.ss.util.CellUtil;
    12. import java.text.ParseException;
    13. import java.text.SimpleDateFormat;
    14. import java.util.Arrays;
    15. import java.util.Date;
    16. import java.util.Optional;
    17. import java.util.TimeZone;
    18. import java.util.function.Function;
    19. /**
    20. * type converter
    21. */
    22. @Slf4j
    23. @Getter
    24. public enum JavaFileTypeEnum {
    25.     STRING("string", SqlTypeName.VARCHAR, Cell::getStringCellValue),
    26.     BOOLEAN("boolean", SqlTypeName.BOOLEAN, Cell::getBooleanCellValue),
    27.     BYTE("byte", SqlTypeName.TINYINT, Cell::getStringCellValue),
    28.     CHAR("char", SqlTypeName.CHAR, Cell::getStringCellValue),
    29.     SHORT("short", SqlTypeName.SMALLINT, Cell::getNumericCellValue),
    30.     INT("int", SqlTypeName.INTEGER, cell -> (Double.valueOf(cell.getNumericCellValue()).intValue())),
    31.     LONG("long", SqlTypeName.BIGINT, cell -> (Double.valueOf(cell.getNumericCellValue()).longValue())),
    32.     FLOAT("float", SqlTypeName.REAL, Cell::getNumericCellValue),
    33.     DOUBLE("double", SqlTypeName.DOUBLE, Cell::getNumericCellValue),
    34.     DATE("date", SqlTypeName.DATE, getValueWithDate()),
    35.     TIMESTAMP("timestamp", SqlTypeName.TIMESTAMP, getValueWithTimestamp()),
    36.     TIME("time", SqlTypeName.TIME, getValueWithTime()),
    37.     UNKNOWN("unknown", SqlTypeName.UNKNOWN, getValueWithUnknown()),;
    38.     // cell type
    39.     private final String typeName;
    40.                 // sql type
    41.     private final SqlTypeName sqlTypeName;
    42.     // value convert func
    43.     private final Function<Cell, Object> cellValueFunc;
    44.     private static final FastDateFormat TIME_FORMAT_DATE;
    45.     private static final FastDateFormat TIME_FORMAT_TIME;
    46.     private static final FastDateFormat TIME_FORMAT_TIMESTAMP;
    47.     static {
    48.         final TimeZone gmt = TimeZone.getTimeZone("GMT");
    49.         TIME_FORMAT_DATE = FastDateFormat.getInstance("yyyy-MM-dd", gmt);
    50.         TIME_FORMAT_TIME = FastDateFormat.getInstance("HH:mm:ss", gmt);
    51.         TIME_FORMAT_TIMESTAMP = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss", gmt);
    52.     }
    53.     JavaFileTypeEnum(String typeName, SqlTypeName sqlTypeName, Function<Cell, Object> cellValueFunc) {
    54.         this.typeName = typeName;
    55.         this.sqlTypeName = sqlTypeName;
    56.         this.cellValueFunc = cellValueFunc;
    57.     }
    58.     public static Optional<JavaFileTypeEnum> of(String typeName) {
    59.         return Arrays
    60.                 .stream(values())
    61.                 .filter(type -> StringUtils.equalsIgnoreCase(typeName, type.getTypeName()))
    62.                 .findFirst();
    63.     }
    64.     public static SqlTypeName findSqlTypeName(String typeName) {
    65.         final Optional<JavaFileTypeEnum> javaFileTypeOptional = of(typeName);
    66.         if (javaFileTypeOptional.isPresent()) {
    67.             return javaFileTypeOptional
    68.                     .get()
    69.                     .getSqlTypeName();
    70.         }
    71.         return SqlTypeName.UNKNOWN;
    72.     }
    73.     public Object getCellValue(Cell cell) {
    74.         return cellValueFunc.apply(cell);
    75.     }
    76.     public static Function<Cell, Object> getValueWithUnknown() {
    77.         return cell -> {
    78.             if (ObjectUtils.isEmpty(cell)) {
    79.                 return null;
    80.             }
    81.             switch (cell.getCellType()) {
    82.                 case STRING:
    83.                     return cell.getStringCellValue();
    84.                 case NUMERIC:
    85.                     if (DateUtil.isCellDateFormatted(cell)) {
    86.                         // 如果是日期类型,返回日期对象
    87.                         return cell.getDateCellValue();
    88.                     }
    89.                     else {
    90.                         // 否则返回数值
    91.                         return cell.getNumericCellValue();
    92.                     }
    93.                 case BOOLEAN:
    94.                     return cell.getBooleanCellValue();
    95.                 case FORMULA:
    96.                     // 对于公式单元格,先计算公式结果,再获取其值
    97.                     try {
    98.                         return cell.getNumericCellValue();
    99.                     }
    100.                     catch (Exception e) {
    101.                         try {
    102.                             return cell.getStringCellValue();
    103.                         }
    104.                         catch (Exception ex) {
    105.                             log.error("parse unknown data error, cellRowIndex:{}, cellColumnIndex:{}", cell.getRowIndex(), cell.getColumnIndex(), e);
    106.                             return null;
    107.                         }
    108.                     }
    109.                 case BLANK:
    110.                     return "";
    111.                 default:
    112.                     return null;
    113.             }
    114.         };
    115.     }
    116.     public static Function<Cell, Object> getValueWithDate() {
    117.         return cell -> {
    118.             Date date = cell.getDateCellValue();
    119.             if(ObjectUtils.isEmpty(date)) {
    120.                 return null;
    121.             }
    122.             try {
    123.                 final String formated = new SimpleDateFormat("yyyy-MM-dd").format(date);
    124.                 Date newDate = TIME_FORMAT_DATE.parse(formated);
    125.                 return (int) (newDate.getTime() / DateTimeUtils.MILLIS_PER_DAY);
    126.             }
    127.             catch (ParseException e) {
    128.                 log.error("parse date error, date:{}", date, e);
    129.             }
    130.             return null;
    131.         };
    132.     }
    133.     public static Function<Cell, Object> getValueWithTimestamp() {
    134.         return cell -> {
    135.             Date date = cell.getDateCellValue();
    136.             if(ObjectUtils.isEmpty(date)) {
    137.                 return null;
    138.             }
    139.             try {
    140.                 final String formated = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    141.                 Date newDate = TIME_FORMAT_TIMESTAMP.parse(formated);
    142.                 return (int) newDate.getTime();
    143.             }
    144.             catch (ParseException e) {
    145.                 log.error("parse timestamp error, date:{}", date, e);
    146.             }
    147.             return null;
    148.         };
    149.     }
    150.     public static Function<Cell, Object> getValueWithTime() {
    151.         return cell -> {
    152.             Date date = cell.getDateCellValue();
    153.             if(ObjectUtils.isEmpty(date)) {
    154.                 return null;
    155.             }
    156.             try {
    157.                 final String formated = new SimpleDateFormat("HH:mm:ss").format(date);
    158.                 Date newDate = TIME_FORMAT_TIME.parse(formated);
    159.                 return newDate.getTime();
    160.             }
    161.             catch (ParseException e) {
    162.                 log.error("parse time error, date:{}", date, e);
    163.             }
    164.             return null;
    165.         };
    166.     }
    167. }
    复制代码
    该枚举类主要管理了
    1. java type
    复制代码
    &
    1. sql type
    复制代码
    &
    1. cell value convert func
    复制代码
    , 方便统一管理类型映射及单元格内容提取时的转换方法(这里借用了java8 function函数特性)
    1. 注: 这里的日期转换只能这样写, 即使用GMT的时区(抄的[code]calcite-file
    复制代码
    ), 要不然输出的日期时间一直有时差...[/code]
    6. 测试查询
    1. package com.ldx.calcite;
    2. import com.ldx.calcite.excel.ExcelSchemaFactory;
    3. import lombok.SneakyThrows;
    4. import lombok.extern.slf4j.Slf4j;
    5. import org.apache.calcite.config.CalciteConnectionProperty;
    6. import org.apache.calcite.jdbc.CalciteConnection;
    7. import org.apache.calcite.schema.Schema;
    8. import org.apache.calcite.schema.SchemaPlus;
    9. import org.apache.calcite.util.Sources;
    10. import org.junit.jupiter.api.AfterAll;
    11. import org.junit.jupiter.api.BeforeAll;
    12. import org.junit.jupiter.api.Test;
    13. import org.testng.collections.Maps;
    14. import java.net.URL;
    15. import java.sql.Connection;
    16. import java.sql.DriverManager;
    17. import java.sql.ResultSet;
    18. import java.sql.ResultSetMetaData;
    19. import java.sql.SQLException;
    20. import java.sql.Statement;
    21. import java.util.Map;
    22. import java.util.Properties;
    23. @Slf4j
    24. public class CalciteExcelTest {
    25.     private static Connection connection;
    26.     private static SchemaPlus rootSchema;
    27.     private static CalciteConnection calciteConnection;
    28.     @BeforeAll
    29.     @SneakyThrows
    30.     public static void beforeAll() {
    31.         Properties info = new Properties();
    32.         // 不区分sql大小写
    33.         info.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(), "false");
    34.         // 创建Calcite连接
    35.         connection = DriverManager.getConnection("jdbc:calcite:", info);
    36.         calciteConnection = connection.unwrap(CalciteConnection.class);
    37.         // 构建RootSchema,在Calcite中,RootSchema是所有数据源schema的parent,多个不同数据源schema可以挂在同一个RootSchema下
    38.         rootSchema = calciteConnection.getRootSchema();
    39.     }
    40.     @Test
    41.     @SneakyThrows
    42.     public void test_execute_query() {
    43.         final Schema schema = ExcelSchemaFactory.INSTANCE.create(resourcePath("file/test.xlsx"));
    44.         rootSchema.add("test", schema);
    45.         // 设置默认的schema
    46.         calciteConnection.setSchema("test");
    47.         final Statement statement = calciteConnection.createStatement();
    48.         ResultSet resultSet = statement.executeQuery("SELECT * FROM user_info");
    49.         printResultSet(resultSet);
    50.         System.out.println("=========");
    51.         ResultSet resultSet2 = statement.executeQuery("SELECT * FROM test.user_info where id > 110 and birthday > '2003-01-01'");
    52.         printResultSet(resultSet2);
    53.         System.out.println("=========");
    54.         ResultSet resultSet3 = statement.executeQuery("SELECT * FROM test.user_info ui inner join  test.role_info ri on ui.role_id = ri.id");
    55.         printResultSet(resultSet3);
    56.     }
    57.     @AfterAll
    58.     @SneakyThrows
    59.     public static void closeResource() {
    60.         connection.close();
    61.     }
    62.     private static String resourcePath(String path) {
    63.         final URL url = CalciteExcelTest.class.getResource("/" + path);
    64.         return Sources.of(url).file().getAbsolutePath();
    65.     }
    66.     public static void printResultSet(ResultSet resultSet) throws SQLException {
    67.         // 获取 ResultSet 元数据
    68.         ResultSetMetaData metaData = resultSet.getMetaData();
    69.         // 获取列数
    70.         int columnCount = metaData.getColumnCount();
    71.         log.info("Number of columns: {}",columnCount);
    72.         // 遍历 ResultSet 并打印结果
    73.         while (resultSet.next()) {
    74.             final Map<String, String> item = Maps.newHashMap();
    75.             // 遍历每一列并打印
    76.             for (int i = 1; i <= columnCount; i++) {
    77.                 String columnName = metaData.getColumnName(i);
    78.                 String columnValue = resultSet.getString(i);
    79.                 item.put(columnName, columnValue);
    80.             }
    81.             log.info(item.toString());
    82.         }
    83.     }
    84. }
    复制代码
    测试结果如下:

    到此这篇关于使用SQL语言查询多个Excel表格的操作方法的文章就介绍到这了,更多相关SQL查询多个Excel表格内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:https://www.jb51.net/database/334629hs2.htm
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表