Конвертер XLS в CSV - PullRequest
       64

Конвертер XLS в CSV

46 голосов
/ 27 марта 2012

Я использую win32.client в python для преобразования моих файлов .xlsx и .xls в .csv.Когда я выполняю этот код, он выдает ошибку.Мой код:

def convertXLS2CSV(aFile):
    '''converts a MS Excel file to csv w/ the same name in the same directory'''

    print "------ beginning to convert XLS to CSV ------"

    try:
        import win32com.client, os
        from win32com.client import constants as c
        excel = win32com.client.Dispatch('Excel.Application')

        fileDir, fileName = os.path.split(aFile)
        nameOnly = os.path.splitext(fileName)
        newName = nameOnly[0] + ".csv"
        outCSV = os.path.join(fileDir, newName)
        workbook = excel.Workbooks.Open(aFile)
        workbook.SaveAs(outCSV, c.xlCSVMSDOS) # 24 represents xlCSVMSDOS
        workbook.Close(False)
        excel.Quit()
        del excel

        print "...Converted " + nameOnly + " to CSV"
    except:
        print ">>>>>>> FAILED to convert " + aFile + " to CSV!"

convertXLS2CSV("G:\\hello.xlsx")

Я не могу найти ошибку в этом коде.Пожалуйста, помогите.

Ответы [ 11 ]

62 голосов
/ 27 марта 2012

Я бы использовал xlrd - он быстрее, кроссплатформенный и работает напрямую с файлом. Стоит отметить, что он не работает с файлами xlsx, поэтому вам нужно сохранить файл Excel как xls. Редактировать: Начиная с версии 0.8.0, xlrd читает обаФайлы XLS и XLSX.

 import xlrd
 import csv

 def csv_from_excel():

    wb = xlrd.open_workbook('your_workbook.xls')
    sh = wb.sheet_by_name('Sheet1')
    your_csv_file = open('your_csv_file.csv', 'wb')
    wr = csv.writer(your_csv_file, quoting=csv.QUOTE_ALL)

    for rownum in xrange(sh.nrows):
        wr.writerow(sh.row_values(rownum))

    your_csv_file.close()
42 голосов
/ 01 октября 2014

Я бы использовал pandas. Тяжелые в вычислительном отношении части написаны на cython или c-extensions для ускорения процесса, а синтаксис очень чистый. Например, если вы хотите превратить «Sheet1» из файла «your_workbook.xls» в файл «your_csv.csv», вы просто используете функцию верхнего уровня read_excel и метод to_csv из DataFrame Класс следующим образом:

import pandas as pd
data_xls = pd.read_excel('your_workbook.xls', 'Sheet1', index_col=None)
data_xls.to_csv('your_csv.csv', encoding='utf-8')

Установка encoding='utf-8' облегчает UnicodeEncodeError, упомянутые в других ответах.

32 голосов
/ 17 сентября 2013

Может быть, кто-то найдет этот готовый к использованию кусок кода полезным.Это позволяет создавать CSV из всех электронных таблиц в книге Excel.

enter image description here

# -*- coding: utf-8 -*-
import xlrd
import csv
from os import sys

def csv_from_excel(excel_file):
    workbook = xlrd.open_workbook(excel_file)
    all_worksheets = workbook.sheet_names()
    for worksheet_name in all_worksheets:
        worksheet = workbook.sheet_by_name(worksheet_name)
        with open('{}.csv'.format(worksheet_name), 'wb') as your_csv_file:
            wr = csv.writer(your_csv_file, quoting=csv.QUOTE_ALL)
            for rownum in xrange(worksheet.nrows):
                wr.writerow([unicode(entry).encode("utf-8") for entry in worksheet.row_values(rownum)])

if __name__ == "__main__":
    csv_from_excel(sys.argv[1])
21 голосов
/ 27 марта 2012

Я бы использовал csvkit , который использует xlrd (для xls) и openpyxl (для xlsx) для преобразования практически любых табличных данных в csv.

После установки, с ее зависимостями, это вопрос:

python in2csv myfile > myoutput.csv

Он заботится обо всех проблемах определения формата, поэтому вы можете передать его практически любому табличному источнику данных. Он также кроссплатформенный (без зависимости от win32).

3 голосов
/ 02 ноября 2016

xlsx2csv на быстрее , чем pandas и xlrd.

xlsx2csv -s 0 crunchbase_monthly_.xlsx cruchbase

Файл Excel обычно поставляется с именем листа.

-s is sheetname index.

затем, будет создана папка cruchbase, каждый лист, принадлежащий xlsx, будет конвертирован в один CSV.

ps csvkit тоже потрясающе.

3 голосов
/ 20 января 2015

@ andi Я проверил ваш код, он отлично работает, НО

В моих листах есть такая колонка

2013-03-06T04: 00: 00

дата и время в одной ячейке

Он искажается во время экспорта, это похоже на экспортируемый файл

41275,0416667

другие столбцы в порядке.

csvkit, с другой стороны, хорошо работает с этим столбцом, но экспортирует только ОДИН лист, а у моих файлов их много.

1 голос
/ 25 января 2018

Цитирование ответа из Скотта Мина , который работает с книгой, содержащей несколько листов:

Вот скрипт на Python getsheets.py ( mirror ), вам следует установить pandas и xlrd перед его использованием.

Запустите это:

pip3 install pandas xlrd  # or `pip install pandas xlrd`

Как это работает?

$ python3 getsheets.py -h
Usage: getsheets.py [OPTIONS] INPUTFILE

Convert a Excel file with multiple sheets to several file with one sheet.

Examples:

    getsheets filename

    getsheets filename -f csv

Options:
-f, --format [xlsx|csv]  Default xlsx.
-h, --help               Show this message and exit.

Преобразование в несколько xlsx:

$ python3 getsheets.py goods_temp.xlsx
Sheet.xlsx Done!
Sheet1.xlsx Done!

All Done!

Преобразование в несколько csv:

$ python3 getsheets.py goods_temp.xlsx -f csv
Sheet.csv Done!
Sheet1.csv Done!

All Done!

getsheets.py:

# -*- coding: utf-8 -*-

import click
import os
import pandas as pd


def file_split(file):
    s = file.split('.')
    name = '.'.join(s[:-1])  # get directory name
    return name


def getsheets(inputfile, fileformat):
    name = file_split(inputfile)
    try:
        os.makedirs(name)
    except:
        pass

    df1 = pd.ExcelFile(inputfile)
    for x in df1.sheet_names:
        print(x + '.' + fileformat, 'Done!')
        df2 = pd.read_excel(inputfile, sheetname=x)
        filename = os.path.join(name, x + '.' + fileformat)
        if fileformat == 'csv':
            df2.to_csv(filename, index=False)
        else:
            df2.to_excel(filename, index=False)
    print('\nAll Done!')


CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])


@click.command(context_settings=CONTEXT_SETTINGS)
@click.argument('inputfile')
@click.option('-f', '--format', type=click.Choice([
    'xlsx', 'csv']), default='xlsx', help='Default xlsx.')
def cli(inputfile, format):
    '''Convert a Excel file with multiple sheets to several file with one sheet.

    Examples:

    \b
        getsheets filename

    \b
        getsheets filename -f csv
    '''
    if format == 'csv':
        getsheets(inputfile, 'csv')
    else:
        getsheets(inputfile, 'xlsx')


cli()
0 голосов
/ 07 апреля 2019

Как бы мне не хотелось полагаться на проприетарное программное обеспечение Windows Excel, которое не является кроссплатформенным, мое тестирование csvkit для .xls, которое использует xlrd под капотом, не смогло правильно проанализировать даты (даже когда используя параметры командной строки для указания формата strptime).

Например, этот xls-файл при анализе с csvkit преобразует ячейку G1 из 12/31/2002 в 37621, тогда как при преобразовании в csv через excel -> save_as (используя ниже) ячейка G1 будет "December 31, 2002".

import re
import os
from win32com.client import Dispatch
xlCSVMSDOS = 24

class CsvConverter(object):
    def __init__(self, *, input_dir, output_dir):
        self._excel = None
        self.input_dir = input_dir
        self.output_dir = output_dir

        if not os.path.isdir(self.output_dir):
            os.makedirs(self.output_dir)

    def isSheetEmpty(self, sheet):
        # https://archive.is/RuxR7
        # WorksheetFunction.CountA(ActiveSheet.UsedRange) = 0 And ActiveSheet.Shapes.Count = 0

        return \
            (not self._excel.WorksheetFunction.CountA(sheet.UsedRange)) \
            and \
            (not sheet.Shapes.Count)

    def getNonEmptySheets(self, wb, as_name=False):
        return [ \
            (sheet.Name if as_name else sheet) \
            for sheet in wb.Sheets \
            if not self.isSheetEmpty(sheet) \
        ]

    def saveWorkbookAsCsv(self, wb, csv_path):
        non_empty_sheet_names = self.getNonEmptySheets(wb, as_name=True)

        assert (len(non_empty_sheet_names) == 1), \
            "Expected exactly 1 sheet but found %i non-empty sheets: '%s'" \
            %(
                len(non_empty_sheet_names),
                "', '".join(name.replace("'", r"\'") for name in non_empty_sheet_names)
            )

        wb.Worksheets(non_empty_sheet_names[0]).SaveAs(csv_path, xlCSVMSDOS)
        wb.Saved = 1

    def isXlsFilename(self, filename):
        return bool(re.search(r'(?i)\.xls$', filename))

    def batchConvertXlsToCsv(self):
        xls_names = tuple( filename for filename in next(os.walk(self.input_dir))[2] if self.isXlsFilename(filename) )

        self._excel = Dispatch('Excel.Application')
        try:
            for xls_name in xls_names:
                csv_path = os.path.join(self.output_dir, '%s.csv' %os.path.splitext(xls_name)[0])
                if not os.path.isfile(csv_path):
                    workbook = self._excel.Workbooks.Open(os.path.join(self.input_dir, xls_name))
                    try:
                        self.saveWorkbookAsCsv(workbook, csv_path)
                    finally:
                        workbook.Close()
        finally:
            if not len(self._excel.Workbooks):
                self._excel.Quit()

            self._excel = None

if __name__ == '__main__':
    self = CsvConverter(
        input_dir='C:\\data\\xls\\',
        output_dir='C:\\data\\csv\\'
    )

    self.batchConvertXlsToCsv()

Вышеприведенное примет input_dir, содержащий .xls, и выведет их в output_dir как .csv - assert будет иметь ровно 1 непустой лист в .xls; если вам нужно обработать несколько листов в несколько CSV, вам нужно отредактировать saveWorkbookAsCsv.

0 голосов
/ 12 февраля 2018

Мы можем использовать Pandas lib of Python для преобразования файла xls в файл csv. Ниже приведен код, который преобразует файл xls в файл csv.импорт панд в виде pd

Чтение файла Excel по локальному пути:

df = pd.read_excel("C:/Users/IBM_ADMIN/BU GPA Scorecard.xlsx",sheetname=1)

Обрезать пробелы в столбцах:

df.columns = df.columns.str.strip()

Отправить кадр данных в файл CSV, который будетсимвол трубы с разделителями и без индекса:

df.to_csv("C:/Users/IBM_ADMIN/BU GPA Scorecard csv.csv",sep="|",index=False)
0 голосов
/ 07 февраля 2017

Я проверил все ответы, но они были слишком медленными для меня. Если у вас установлен Excel, вы можете использовать COM.

Сначала я думал, что это будет медленнее, поскольку он будет загружать все для реального приложения Excel, но не для больших файлов. Возможно, из-за того, что алгоритм открытия и сохранения файлов использует сильно оптимизированный скомпилированный код, ребята из Microsoft все-таки за него много зарабатывают.

import sys
import os
import glob
from win32com.client import Dispatch

def main(path):
    excel = Dispatch("Excel.Application")
    if is_full_path(path):
        process_file(excel, path)
    else:
        files = glob.glob(path)
        for file_path in files:
            process_file(excel, file_path)
    excel.Quit()

def process_file(excel, path):
    fullpath = os.path.abspath(path)
    full_csv_path = os.path.splitext(fullpath)[0] + '.csv'
    workbook = excel.Workbooks.Open(fullpath)
    workbook.Worksheets(1).SaveAs(full_csv_path, 6)
    workbook.Saved = 1
    workbook.Close()


def is_full_path(path):
    return path.find(":") > -1

if __name__ == '__main__':
    main(sys.argv[1])

Это очень сырой код, который не будет проверять ошибки, распечатывать справку или что-либо еще, он просто создаст CSV-файл для каждого файла, который соответствует шаблону, который вы ввели в функцию, так что вы можете пакетно обрабатывать только много файлов запуск приложения Excel один раз.

...