使用 xlwt,在达到 xls 行限制时创建一个新的 sheet
Using xlwt, create a new sheet anytime xls row limit is reached
我目前正在编写一个 python 脚本,它将获取任意数量的 csv 文件并从中创建 .xls 文件。不幸的是,其中一些 csv 文件的行数大于 65536,这意味着它们不能存在于一个 .xls sheet 上。我想做的是想出一种在达到该行数时生成新 sheet 的方法。作为参考,这是我目前使用的代码:
import csv, xlwt, glob, ntpath
files = glob.glob("C:/Users/waldiesamuel/326/*.csv")
bold = xlwt.easyxf('font: bold on')
for i in files:
org_file = open(i, 'r')
reader = csv.reader((org_file), delimiter=",")
workbook = xlwt.Workbook()
sheet = workbook.add_sheet("SQL Results")
path = ntpath.dirname(i)
file = ntpath.basename(i)
for rowi, row in enumerate(reader):
for coli, value in enumerate(row):
if coli == 0:
sheet.write(rowi,coli,value,bold)
else:
sheet.write(rowi,coli,value)
workbook.save(path + file + '.xls')
我的想法是
for rowi, row in enumerate(reader):
我可以使用 if 语句检查行是否大于 65536,但我不确定如何从那里创建新变量。
编辑:
我找到了一个潜在的解决方案,但失败了,并通过答案进行了解释。我将其作为编辑包含在此处,以便每个人都可以遵循思考过程:
看来,因为 xlwt 检查以明确确保您添加的行数不超过 65536 行,所以这可能不可行。通过将 sheet 变量更改为字典,我想出了一个我认为很聪明的解决方案,如下所示:
sheet = {1: workbook.add_sheet("SQL Results")}
然后初始化两个变量作为计数器:
sheet_counter = 1
dict_counter = 2
然后在第一个 for 循环中使用它作为条件,这将重置行索引并允许 xlwt 继续写入新的 sheet:
if rowi == 65536:
sheet[dict_counter] = workbook.add_sheet("SQL Results (" + str(dict_counter) + ")")
sheet_counter += 1
dict_counter += 1
rowi = 1
else:
pass
不幸的是,即使这样做仍然会导致 xlwt 在 row
变量递增超过 65536 时抛出以下错误:
Traceback (most recent call last):
File "xlstest.py", line 35, in <module>
sheet[sheet_counter].write(rowi,coli,value,bold)
File "C:\Users\waldiesamuel\AppData\Local\Programs\Python\Python35-32\lib\site-packages\xlwt\Worksheet.py", line 1088, in write
self.row(r).write(c, label, style)
File "C:\Users\waldiesamuel\AppData\Local\Programs\Python\Python35-32\lib\site-packages\xlwt\Worksheet.py", line 1142, in row
self.__rows[indx] = self.Row(indx, self)
File "C:\Users\waldiesamuel\AppData\Local\Programs\Python\Python35-32\lib\site-packages\xlwt\Row.py", line 43, in __init__
raise ValueError("row index was %r, not allowed by .xls format" % rowx)
ValueError: row index was 65537, not allowed by .xls format
xlwt 是
a library for developers to use to generate spreadsheet files
compatible with Microsoft Excel versions 95 to 2003.
(see here)
在那些 excel 版本中,最大行数限制为 65536。请参阅 here。
尝试 XlsxWriter,它符合 Excel 2007,行数最多可达 1,048,576。
您的解决方案的问题是您试图将 rowi
(来自您的 enumerate()
语句)重置回 1,但它会在下一个循环中重置。
我认为,实现所需内容的最简单方法是更改引用行和 sheet 的方式。您可以使用 floor division and modulo 运算符分别为您提供 sheet 编号和行号。
if rowi % 65536 == 0:
sheet[dict_counter] = workbook.add_sheet("SQL Results (" + str(dict_counter) + ")")
sheet_counter += 1 # Not sure if you use this anywhere else - it can probably go
dict_counter += 1
else:
pass
sheetno = rowi // 65536
rowno = rowi %% 65536
sheet[sheetno].write(rowno,coli,value,bold)
我目前正在编写一个 python 脚本,它将获取任意数量的 csv 文件并从中创建 .xls 文件。不幸的是,其中一些 csv 文件的行数大于 65536,这意味着它们不能存在于一个 .xls sheet 上。我想做的是想出一种在达到该行数时生成新 sheet 的方法。作为参考,这是我目前使用的代码:
import csv, xlwt, glob, ntpath
files = glob.glob("C:/Users/waldiesamuel/326/*.csv")
bold = xlwt.easyxf('font: bold on')
for i in files:
org_file = open(i, 'r')
reader = csv.reader((org_file), delimiter=",")
workbook = xlwt.Workbook()
sheet = workbook.add_sheet("SQL Results")
path = ntpath.dirname(i)
file = ntpath.basename(i)
for rowi, row in enumerate(reader):
for coli, value in enumerate(row):
if coli == 0:
sheet.write(rowi,coli,value,bold)
else:
sheet.write(rowi,coli,value)
workbook.save(path + file + '.xls')
我的想法是
for rowi, row in enumerate(reader):
我可以使用 if 语句检查行是否大于 65536,但我不确定如何从那里创建新变量。
编辑:
我找到了一个潜在的解决方案,但失败了,并通过答案进行了解释。我将其作为编辑包含在此处,以便每个人都可以遵循思考过程:
看来,因为 xlwt 检查以明确确保您添加的行数不超过 65536 行,所以这可能不可行。通过将 sheet 变量更改为字典,我想出了一个我认为很聪明的解决方案,如下所示:
sheet = {1: workbook.add_sheet("SQL Results")}
然后初始化两个变量作为计数器:
sheet_counter = 1
dict_counter = 2
然后在第一个 for 循环中使用它作为条件,这将重置行索引并允许 xlwt 继续写入新的 sheet:
if rowi == 65536:
sheet[dict_counter] = workbook.add_sheet("SQL Results (" + str(dict_counter) + ")")
sheet_counter += 1
dict_counter += 1
rowi = 1
else:
pass
不幸的是,即使这样做仍然会导致 xlwt 在 row
变量递增超过 65536 时抛出以下错误:
Traceback (most recent call last):
File "xlstest.py", line 35, in <module>
sheet[sheet_counter].write(rowi,coli,value,bold)
File "C:\Users\waldiesamuel\AppData\Local\Programs\Python\Python35-32\lib\site-packages\xlwt\Worksheet.py", line 1088, in write
self.row(r).write(c, label, style)
File "C:\Users\waldiesamuel\AppData\Local\Programs\Python\Python35-32\lib\site-packages\xlwt\Worksheet.py", line 1142, in row
self.__rows[indx] = self.Row(indx, self)
File "C:\Users\waldiesamuel\AppData\Local\Programs\Python\Python35-32\lib\site-packages\xlwt\Row.py", line 43, in __init__
raise ValueError("row index was %r, not allowed by .xls format" % rowx)
ValueError: row index was 65537, not allowed by .xls format
xlwt 是
a library for developers to use to generate spreadsheet files compatible with Microsoft Excel versions 95 to 2003. (see here)
在那些 excel 版本中,最大行数限制为 65536。请参阅 here。
尝试 XlsxWriter,它符合 Excel 2007,行数最多可达 1,048,576。
您的解决方案的问题是您试图将 rowi
(来自您的 enumerate()
语句)重置回 1,但它会在下一个循环中重置。
我认为,实现所需内容的最简单方法是更改引用行和 sheet 的方式。您可以使用 floor division and modulo 运算符分别为您提供 sheet 编号和行号。
if rowi % 65536 == 0:
sheet[dict_counter] = workbook.add_sheet("SQL Results (" + str(dict_counter) + ")")
sheet_counter += 1 # Not sure if you use this anywhere else - it can probably go
dict_counter += 1
else:
pass
sheetno = rowi // 65536
rowno = rowi %% 65536
sheet[sheetno].write(rowno,coli,value,bold)