OleDb连接到Excel; 如何选择固定宽度,无界高度?

Ste*_*per 5 c# oledb excel

我正在使用OleDb从excel电子表格中选择数据.每个电子表格都可以包含许多小表,也可能包含标题和标签等家具.所以它可能看起来像这样,我们有两个表和一些标题;

            A           B         C          D
    1    .           .         .          .
    2    .           .         .          .
    3    Table1      .         .          .
    4    Header1     HEADER2   .          .
    5    h           huey      .          .
    6    d           dewey     .          .
    7    l           loius     .          .
    8    s           scrooge   .          .
    9    .           .         .          .
    10   .           .         .          .
    11   .           .         .          .
    12   .           .         .          .
    13   .           Table 2   .          .
    14   .           HEADER1   HEADER2    HEADER3
    15   .           1         foo        x
    16   .           2         bar        y
    17   .           3         baz        z
    18   .           .         .          .
    19   .           .         .          .

在上一步中,用户选择了他们感兴趣的表的标题; 在这种情况下,看表2他们将选择范围B14:D14.

保存这些设置,然后我需要查询该表.随着电子表格数据的更新,它可能会反复发生; 可以随时添加更多行,但标题始终是固定的.标记数据结尾的标记(空行)

要选择表中的数据,我正在编写这样的查询;

SELECT * FROM [Sheet1$B14:D65535]
Run Code Online (Sandbox Code Playgroud)

选择表2中的数据,然后手动检查sentinel行,但这似乎不满意.Excel 2003只能读取65,535行(uint16),但excel 2007可以读取更多行(uint32),因此我必须编写代码,根据文件的扩展名为Excel 2003和2007提供不同的查询(.xls vs. XLS?).

有没有人知道写一个查询的方法;

  • '选择B14的所有内容'?
  • '选择B-> D列中的所有内容
  • '选择B12:D*',其中*表示'你能做的一切'

Joh*_*hin 9

先决条件:您可以在代码中轻松确定最大行数.

假设(1)每个SELECT有很大的开销,所以一次选择一行很慢(2)选择64K或8M行(即使空白)很慢......所以你想看看中间的某个地方是否可以快点.试试这个:

一次选择CHUNKSIZE(例如100或1000)行(否则,否则会超过MAX_ROWS).扫描每个块以查找标记数据结尾的空行.

更新:实际上回答明确的问题:

问:有没有人知道编写查询的方法;

Q1:'选择B14'的所有内容?

A1:select * from [Sheet1$B12:]不起作用.您将不得不...B12:IV在Excel 2003中以及Excel 2007中的任何内容.但是您不需要它,因为您知道最右边的列是什么; 见下文.

Q2:'选择B-> D列中的所有内容

A2: select * from [Sheet1$B:D]

Q3:'选择B12:D *' *表示"你能做的一切"

A3:从[Sheet1 $ B12:D]中选择*

使用以下代码使用Python 2.5进行测试:

import win32com.client
import sys
filename, sheetname, range = sys.argv[1:4]
DSN= """
    PROVIDER=Microsoft.Jet.OLEDB.4.0;
    DATA SOURCE=%s;
    Extended Properties='Excel 8.0;READONLY=true;IMEX=1';
    """ % filename
conn = win32com.client.Dispatch("ADODB.Connection")
conn.Open(DSN)
rs = win32com.client.Dispatch("ADODB.Recordset")
sql = (
    "SELECT * FROM [Excel 8.0;HDR=NO;IMEX=1;Database=%s;].[%s$%s]"
    % (filename, sheetname, range)
    )
rs.Open(sql, conn)
nrows = 0
while not rs.EOF:
    nrows += 1
    nf = rs.Fields.Count
    values = [rs.Fields.Item(i).Value for i in xrange(nf)]
    print nrows, values
    if not any(value is not None for value in values):
        print "sentinel found"
        break
    rs.MoveNext()
rs.Close()
conn.Close()
Run Code Online (Sandbox Code Playgroud)