简体   繁体   English

使用xlwt,只要达到xls行限制,就创建一个新工作表

[英]Using xlwt, create a new sheet anytime xls row limit is reached

I'm currently writing a python script that will take an arbitrary number of csv files and create .xls files from them. 我目前正在编写一个python脚本,该脚本将使用任意数量的csv文件并从中创建.xls文件。 Unfortunately, some of these csv files have row counts greater than 65536, which means that they can't exist on one .xls sheet. 不幸的是,其中某些csv文件的行数大于65536,这意味着它们不能存在于一个.xls工作表中。 What I would like to do is come up with a way to generate a new sheet when that number of rows is reached. 我想做的是想出一种当达到该行数时生成新工作表的方法。 For reference, here is the code I'm currently using: 供参考,这是我当前正在使用的代码:

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')

My thought is that around 我的想法是周围

for rowi, row in enumerate(reader):

I could use an if statement to check if row is greater than 65536, but I'm not sure how to create a new variable from there. 我可以使用if语句来检查row是否大于65536,但是我不确定如何从那里创建一个新变量。

Edit: 编辑:

I found a potential solution, which failed, and was explained by the answer. 我找到了一个可能的解决方案,但失败了,并给出了答案。 I'm including it here as an edit so everyone can follow the thought process: 我将其作为编辑内容包括在内,以便每个人都可以遵循以下思想过程:

So it appears that because xlwt checks to specifically make sure you're not adding more than 65536 rows, this might not be doable. 如此看来,由于xlwt进行检查以明确确保您添加的行不超过65536行,因此这可能不可行。 I had come up with what I thought was a clever solution, by changing my sheet variable to a dict, like so: 通过将工作表变量更改为dict,我想出了一个我认为是聪明的解决方案,如下所示:

sheet = {1: workbook.add_sheet("SQL Results")}

then initializing two variables to serve as counters: 然后初始化两个变量以用作计数器:

sheet_counter = 1
dict_counter = 2

and then using that for a conditional within the first for loop that would reset the row index and allow xlwt to continue writing to a new sheet: 然后将其用于第一个for循环中的条件,该条件将重置行索引并允许xlwt继续写入新工作表:

if rowi == 65536:
    sheet[dict_counter] = workbook.add_sheet("SQL Results (" + str(dict_counter) + ")")
    sheet_counter += 1
    dict_counter += 1
    rowi = 1
else:
    pass

Unfortunately, even doing so still causes xlwt to throw the following error when the row variable increments beyond 65536: 不幸的是,即使这样做仍然会导致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 is xlwt是

a library for developers to use to generate spreadsheet files compatible with Microsoft Excel versions 95 to 2003. (see here ) 供开发人员用来生成与Microsoft Excel版本95至2003兼容的电子表格文件的库。(请参见此处

In those excel versions the maximal number of rows is limited by 65536. See here . 在那些excel版本中,最大行数受65536限制。请参见此处

Try XlsxWriter which is compliant with Excel 2007 and number of rows can be up to 1,048,576. 尝试使用与Excel 2007兼容的XlsxWriter ,并且行数最多可以为1,048,576。

The problem with your solution is that you are trying to reset rowi (which comes from your enumerate() statement) back to 1, but it is reset on the next loop. 解决方案的问题在于,您试图将rowi (来自enumerate()语句)重置为1,但是在下一个循环中将其重置。

The easiest way to achieve what you want, I think, is to change the way you reference rows and sheets. 我认为,实现所需目标的最简单方法是更改​​引用行和工作表的方式。 You can use the floor division and modulo operators to give you the sheet number and row numbers respectively. 您可以使用楼层除法运算符分别为您提供工作表号和行号。

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM