2017-04-30 11 views
0

Java 라이브러리 Jackcess를 사용하여 Access 데이터베이스에서 데이터를 읽으려고합니다. 데이터베이스에는 여러 테이블과 쿼리가 있으며, 그 중 일부는 파일 시스템의 Excel 시트를 가리키는 연결된 테이블입니다.Excel 시트가있는 연결된 테이블을 사용하는 Access 데이터베이스 읽기

나는 연결된 데이터의 해석을 가로 채기 위해 LinkResolver을 사용할 수 있다는 것을 알았지 만 하나의 테이블에 대한 데이터뿐만 아니라 본격적인 데이터베이스를 기대합니다.

쉽게 Apache POI를 사용하여 Excel 파일을 열고 필요한 데이터를 추출 할 수 있지만 LinkResolver에서 데이터를 전달하는 방법을 모르겠습니다.

Excel 파일의 위치를 ​​제공하거나 Excel 파일에서 데이터를 읽은 다음 Jackcess로 다시 전달하여 연결된 데이터를 성공적으로로드 할 수있는 가장 간단한 방법은 무엇입니까?

+0

POI를 통해 관련 데이터에 액세스하는 것과 달리 Jackcess API를 통해 데이터를 구체적으로로드해야하는 이유가 있습니까? – jtahlborn

+0

실제로 Access 데이터베이스에서 데이터를 읽으려는 경우 Excel 파일이 일부 쿼리에만 필요하며 Jackcess는 링크가 올바르게 해석되지 않고 실패합니다. – centic

+0

나는 이해한다고 생각하지 않는다. Jackcess 내에서 "원격"테이블을 읽는 것을 피할 수는 없습니까? 또는 ucanaccess를 사용하여 여러 테이블로 실제 SQL 쿼리를 실행하고 있습니까? – jtahlborn

답변

2

현재 LinkResolver API는 다른 데이터베이스의 "원격"테이블 인스턴스를로드하기 위해 작성되었습니다. 모든 유형의 외부 파일에 대한 범용 API로 제작되지 않았습니다. Jackcess 프로젝트를 통해 기능 요청을 확실히 제출할 수 있습니다.

업데이트 :

는 2.1.7 릴리스로, jackcess는 (임시 DB를 사용하여) 데이터베이스에 액세스하지 않은 파일에서로드 연결된 테이블을 용이하게하기 위해 CustomLinkResolver 유틸리티를 제공합니다.

+0

고마워, 2.1.7, 나에 대한 사용자 지정 코드가 적어 이제는 멋지게 작동한다. – centic

+0

@centic - 끝내 주니 기뻤습니다! – jtahlborn

1

Excel 파일의 내용으로 임시 데이터베이스를 만드는 LinkResolver의 다음 초기 구현을 생각해 냈습니다. 임시 데이터베이스의 클로즈 처리 (close-handling) 및 임시 파일 제거 (temporary-file-removal)와 같은 몇 가지 사항이 여전히 부족하지만 기본 목적으로 작동하는 것으로 보입니다.

/** 
* 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); 
    } 
} 
+0

ㅎ, 나는 실제로 비슷한 제안을 게시하기 위해이 질문으로 돌아 왔습니다. 나는 Jackcess가 LinkResolver를위한 기본 클래스를 가질 수 있다고 생각했다. LinkResolver는 다른 파일에서 데이터를로드하고 임시 데이터베이스로 가져 오는 후크를 제공한다. – jtahlborn

+0

예, 여기에 더 많은 지원이 필요합니다. 또한 jackcess가 주 데이터베이스에서 테이블을 찾는 것처럼 링크 된 테이블을 찾지 못하는 것처럼 여기에 추가로드 블록을 추가 한 것으로 보입니다. – centic

+0

예, 저를 놀라게하지 않을 것입니다. 링크 된 물건을 많이 사용하지 않은 (내가 알고있어), 그리고 하나의 DB에서 다른 테이블 인스턴스를 전달하는 스케치 일종입니다. 버그가 발견되면 주 프로젝트 사이트에서 [신고하십시오] (https://sourceforge.net/p/jackcess/bugs/)하십시오. – jtahlborn