【问题标题】:Splitting CSV file into multiple sheets in an Excel file based on row limit argument基于行限制参数将CSV文件拆分为Excel文件中的多个工作表
【发布时间】:2018-02-12 08:36:39
【问题描述】:

您好,我正在尝试运行我在 github 中找到的实用程序脚本 https://gist.github.com/Athmailer/4cdb424f03129248fbb7ebd03df581cd

更新 1: 嗨,我对逻辑进行了更多修改,以便不再将 csv 拆分为多个 csv,而是创建一个包含拆分的多个工作表的单个 excel 文件。下面是我的代码

import os
import csv
import openpyxl
import argparse

def find_csv_filenames( path_to_dir, suffix=".csv" ):
    filenames = os.listdir(path_to_dir)
    return [ filename for filename in filenames if filename.endswith( suffix ) ]

def is_binary(filename):
    """
    Return true if the given filename appears to be binary.
    File is considered to be binary if it contains a NULL byte.
    FIXME: This approach incorrectly reports UTF-16 as binary.
    """
    with open(filename, 'rb') as f:
        for block in f:
            if '\0' in block:
                return True
    return False

def split(filehandler, delimiter=',', row_limit=5000,
    output_name_template='.xlsx', output_path='.', keep_headers=True):

class MyDialect(csv.excel):
    def __init__(self, delimiter=','):
        self.delimiter = delimiter
    lineterminator = '\n'

my_dialect = MyDialect(delimiter=delimiter)
reader = csv.reader(filehandler, my_dialect)

index = 0
current_piece = 1

# Create a new Excel workbook
# Create a new Excel sheet with name Split1
current_out_path = os.path.join(
     output_path,
     output_name_template
)
wb = openpyxl.Workbook()
ws = wb.create_sheet(index=index, title="Split" + str(current_piece))
current_limit = row_limit

if keep_headers:
    headers = reader.next()
    ws.append(headers)

for i, row in enumerate(reader):
    if i + 1 > current_limit:
        current_piece += 1
        current_limit = row_limit * current_piece
        ws = wb.create_sheet(index=index, title="Split" + str(current_piece))
        if keep_headers:
            ws.append(headers)
    ws.append(row)

wb.save(current_out_path)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Splits a CSV file into multiple pieces.',
                                     prefix_chars='-+')
    parser.add_argument('-l', '--row_limit', type=int, default=5000,
                        help='The number of rows you want in each output file. (default: 5000)')
    args = parser.parse_args()
    #Check if output path exists else create new output folder
    output_path='Output'
    if not os.path.exists(output_path):
        os.makedirs(output_path)

    with open('Logger.log', 'a+') as logfile:
        logfile.write('Filename --- Number of Rows\n')
        logfile.write('#Unsplit\n')
        #Get list of all csv's in the current folder
        filenames = find_csv_filenames(os.getcwd())
        filenames.sort()
        rem_filenames = []
        for filename in filenames:
            if is_binary(filename):
                logfile.write('{} --- binary -- skipped\n'.format(filename))
                rem_filenames.append(filename)
            else:
                with open(filename, 'rb') as infile:
                    reader_file = csv.reader(infile,delimiter=";",lineterminator="\n")
                    value = len(list(reader_file))
                    logfile.write('{} --- {} \n'.format(filename,value))

        filenames = [item for item in filenames if item not in rem_filenames]
        filenames.sort()
        logfile.write('#Post Split\n')
        for filename in filenames:
            #try:
            with open(filename, 'rb') as infile:
                name = filename.split('.')[0]
                split(filehandler=infile,delimiter=';',row_limit=args.row_limit,output_name_template= name + '.xlsx',output_path='Output')

我有一个名为“CSV 文件”的文件夹,其中包含许多需要拆分的 csv。 我将此实用程序脚本保存在同一个文件夹中

运行脚本时出现以下错误:

    Traceback (most recent call last):
  File "csv_split.py", line 96, in <module>
    split(filehandler=infile,delimiter=';',row_limit=args.row_limit,output_name_template= name + '.xlsx',output_path='Output')
  File "csv_split.py", line 57, in split
    ws.append(row)
  File "/home/ramakrishna/.local/lib/python2.7/site-packages/openpyxl/worksheet/worksheet.py", line 790, in append
    cell = Cell(self, row=row_idx, col_idx=col_idx, value=content)
  File "/home/ramakrishna/.local/lib/python2.7/site-packages/openpyxl/cell/cell.py", line 114, in __init__
    self.value = value
  File "/home/ramakrishna/.local/lib/python2.7/site-packages/openpyxl/cell/cell.py", line 294, in value
    self._bind_value(value)
  File "/home/ramakrishna/.local/lib/python2.7/site-packages/openpyxl/cell/cell.py", line 191, in _bind_value
    value = self.check_string(value)
  File "/home/ramakrishna/.local/lib/python2.7/site-packages/openpyxl/cell/cell.py", line 156, in check_string
    raise IllegalCharacterError
openpyxl.utils.exceptions.IllegalCharacterError

有人可以告诉我是否必须添加另一个 for 循环并遍历行中的每个单元格并将其附加到工作表中,还是可以一次性完成。另外,我似乎使这个逻辑变得很笨拙,可以进一步优化吗。

供您参考的文件夹结构

【问题讨论】:

  • 用法信息明确告诉你应该单独传文件名,不带任何input_file=的东西:python2 splitter.py 'Sports &amp; Outdoors 2017-08-26'
  • 如果您使用的是 ubuntu,我认为将blash 拆分为任何 python 脚本更明智。 split file using ubuntu terminal
  • @AnuragMisra 命令行split 是否也将标头带入拆分部分?
  • @DYZ 是的。! split file by keeping header

标签: python csv utility


【解决方案1】:

您必须只传递文件名作为命令行参数:

python splitter.py 'Sports & Outdoors 2017-08-26'

另外,我尝试运行上面的脚本,无论我运行什么 CSS,它都不会返回第一行(通常应该是标题),尽管 keep_headers = True。设置keep_headers = False也会打印出标题行,这有点违反直觉。

此脚本旨在读取单个 CSV。如果要读取目录中的每个 CSV,则需要创建另一个脚本来循环遍历该目录中的所有文件。

import splitter as sp
import os

files = [ f for f in os.listdir('/your/directory') if f[-4:] == '.csv' ]
for file in files:
    with open(file, 'r') as f:
        sp.split(f)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多