阅读一个访问数据库,该数据库使用带有Excel表的链接表



我正在尝试使用Java Library Jackcess从访问数据库中读取数据。该数据库有几个表和查询,其中一些是链接的表,指向文件系统上的excel表。

我看到我可以使用LinkResolver拦截链接数据的分辨率,但是它希望有一个成熟的数据库,而不仅仅是一个单个表的数据。

我可以轻松地使用Apache Poi打开Excel文件并提取必要的数据,但是我不知道如何通过LinkResolver中的数据传递数据。

提供Excel文件位置或从Excel文件中读取数据并将其传递给Jackcess的最简单方法是什么?

在此时间点,LinkResolver API仅用于从其他数据库中加载"远程"表实例。它不是用于任何类型的外部文件的通用API。您当然可以通过Jackcess项目提交功能请求。

更新:

截至2.1.7发行版,Jackcess提供了CustomLinkResolver实用程序,以促进来自不访问数据库的文件(使用临时DB(的加载链接表。

我提出了以下最初的linkResolver初始实现,该实现构建了一个临时数据库,其中excel文件中的内容。它仍然缺乏一些临时数据库的紧密处理和临时文件的东西,但它似乎用于基本目的。

/**
 * Sample LinkResolver which reads the data from an Excel file
 * The data is read from the first sheet and needs to contain a
 * header-row with column-names and then data-rows with string/numeric values.
 */
public class ExcelFileLinkResolver implements LinkResolver {
    private final LinkResolver parentResolver;
    private final String fileNameInDB;
    private final String tableName;
    private final File excelFile;
    public ExcelFileLinkResolver(LinkResolver parentResolver, String fileNameInDB, File excelFile, String tableName) {
        this.parentResolver = parentResolver;
        this.fileNameInDB = fileNameInDB;
        this.excelFile = excelFile;
        this.tableName = tableName;
    }
    @Override
    public Database resolveLinkedDatabase(Database linkerDb, String linkeeFileName) throws IOException {
        if(linkeeFileName.equals(fileNameInDB)) {
            // TODO: handle close or create database in-memory if possible
            File tempFile = File.createTempFile("LinkedDB", ".mdb");
            Database linkedDB = DatabaseBuilder.create(Database.FileFormat.V2003, tempFile);
            try (Workbook wb = WorkbookFactory.create(excelFile, null, true)) {
                TableBuilder tableBuilder = new TableBuilder(tableName);
                Table table = null;
                List<Object[]> rows = new ArrayList<>();
                for(org.apache.poi.ss.usermodel.Row row : wb.getSheetAt(0)) {
                    if(table == null) {
                        for(Cell cell : row) {
                            tableBuilder.addColumn(new ColumnBuilder(cell.getStringCellValue()
                                    // column-names cannot contain some characters
                                    .replace(".", ""),
                                    DataType.TEXT));
                        }
                        table = tableBuilder.toTable(linkedDB);
                    } else {
                        List<String> values = new ArrayList<>();
                        for(Cell cell : row) {
                            if(cell.getCellTypeEnum() == CellType.NUMERIC) {
                                values.add(Double.toString(cell.getNumericCellValue()));
                            } else {
                                values.add(cell.getStringCellValue());
                            }
                        }
                        rows.add(values.toArray());
                    }
                }
                Preconditions.checkNotNull(table, "Did not have a row in " + excelFile);
                table.addRows(rows);
            } catch (InvalidFormatException e) {
                throw new IllegalStateException(e);
            }
            return linkedDB;
        }
        return parentResolver.resolveLinkedDatabase(linkerDb, linkeeFileName);
    }
}

最新更新