我正在使用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?).
有没有人知道写一个查询的方法;
先决条件:您可以在代码中轻松确定最大行数.
假设(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)