2012-03-27 169 views
37

我在使用winthon.client轉換我的.xlsx和.xls文件到.csv中。當我執行此代碼時,它提供了一個錯誤。我的代碼是: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") 

我無法在此代碼中找到該錯誤。請幫忙。

+2

請將錯誤和全面反饋 – agf 2012-03-27 06:33:12

+7

首先除去try/except,否則不會得到如此有用的錯誤。 – SpliFF 2012-03-27 06:34:40

回答

50

我會使用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() 
+2

不應該是'wr.writerow(sh.row_values(rownum))'?請參閱[這裏](https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html#sheet.Sheet.row_values-method)。 – kuujo 2012-10-22 22:45:39

+2

它是否支持從xls datmode到正常日期時間的日期時間轉換 – sharafjaffri 2012-11-29 13:34:08

+0

最新版本適用於xlsx文件:https://pypi.python.org/pypi/xlrd/0.9.2 – Jetse 2013-07-23 14:13:37

17

我會用csvkit,它使用xlrd(用於XLS)和openpyxl(對於XLSX)轉換幾乎任何表格數據爲csv。

一旦安裝後,與它的依賴,這是一個事:

python in2csv myfile > myoutput.csv 

它需要的所有格式檢測問題的關心,所以你可以通過它幾乎任何表格數據源。它也是跨平臺的(沒有win32依賴)。

+0

也喜歡這個工具。與這個問題不太相關,但我在[本書](http://shop.oreilly.com/product/0636920032823.do)中提到了這個csvkit的東西,以及一些其他的數據處理實用工具,可以讓你在你的shell內部轉換數據。 – devforfu 2017-06-15 10:11:35

27

也許有人會發現這個隨時可用的代碼很有用。它允許從Excel工作簿中的所有電子表格創建CSV。

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]) 
+0

只是幾個註釋:一些工作表可能是空的。我沒有看到生成空CSV文件的實用工具,在做任何事之前,最好先在工作表上進行評估。 – 2014-07-16 19:10:13

+0

另外,最好爲CSV文件使用上下文;) – 2014-07-16 19:10:35

+1

您可以跳過空工作表,使用'if worksheet.nrows == 0:continue' – duhaime 2015-05-01 17:28:51

25

我會用pandas。計算量大的部分是用cython或c-extensions編寫的,以加速進程並且語法非常乾淨。例如,如果要將文件「your_workbook.xls」中的「Sheet1」轉換爲文件「your_csv.csv」,則只需使用頂級函數read_excelDataFrame類中的方法to_csv,如下所示:

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

+0

它不起作用,以防在行中有其他語言文本時它不起作用。 ?在文本 – 2016-09-05 05:16:04

+1

@philE這太慢了。使用xlsx2csv – CodeFarmer 2016-11-02 05:47:35

+0

關於處理可能在excel單元格內容中的換行符的任何提示? – Gyan 2017-07-05 14:00:21

2

@andi我測試你的代碼,它的偉大工程,但

在我的牀單有這樣

2013-03-06T04列:00:00

日期和時間在同一小區

它出口時得到亂碼,是這樣的導出文件

41275.0416667

其他欄都可以。

另一方面,csvkit與該列確實無關,但只導出一張表,而我的文件有很多。

3

xlsx2csv比熊貓和xlrd更快

xlsx2csv -s 0 crunchbase_monthly_.xlsx cruchbase 

excel文件通常帶有n個sheetname。

-s is sheetname index. 

然後,將創建cruchbase文件夾,每個屬於xlsx的工作表將被轉換爲單個csv。

p.s. csvkit也很棒。

0

使用xlrd是一個有缺陷的方式來執行此操作,因爲您在Excel中丟失日期格式。

我的用例如下。

將Excel文件與多個工作表合併,並將其轉換爲各自的文件。

我已經完成了這個使用xlsx2csv庫並使用子進程調用它。

import csv 
import sys, os, json, re, time 
import subprocess 

def csv_from_excel(fname): 
    subprocess.Popen(["xlsx2csv " + fname + " --all -d '|' -i -p " 
         "'<New Sheet>' > " + 'test.csv'], shell=True) 

    return 

lstSheets = csv_from_excel(sys.argv[1]) 

time.sleep(3) # system needs to wait a second to recognize the file was written 

with open('[YOUR PATH]/test.csv') as f: 
    lines = f.readlines() 
    firstSheet = True 

    for line in lines: 
     if line.startswith('<New Sheet>'): 
      if firstSheet: 
       sh_2_fname = line.replace('<New Sheet>', '').strip().replace(' - ', '_').replace(' ','_') 
       print(sh_2_fname) 
       sh2f = open(sh_2_fname+".csv", "w") 
       firstSheet = False 
      else: 
       sh2f.close() 
       sh_2_fname = line.replace('<New Sheet>', '').strip().replace(' - ', '_').replace(' ','_') 
       print(sh_2_fname) 
       sh2f = open(sh_2_fname+".csv", "w") 
     else: 
      sh2f.write(line) 
sh2f.close() 
0

我已經測試過所有的聲音,但它們對我來說都太慢了。如果您安裝了Excel,則可以使用COM。

我以爲最初它會比較慢,因爲它會爲實際的Excel應用程序加載所有內容,但它不適用於大文件。也許是因爲用於打開和保存文件的算法運行了大量優化的編譯代碼,畢竟微軟爲它賺了很多錢。

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應用程序。

1

引述answerScott Ming,其中包含多張工作簿的工作原理:

這裏是一個Python腳本getsheets.pymirror),你應該使用它之前安裝pandasxlrd

運行以下命令:

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

我們可以使用Python的熊貓lib添加到conevert 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文件,該文件將被管道符號delimted和無索引:

df.to_csv("C:/Users/IBM_ADMIN/BU GPA Scorecard csv.csv",sep="|",index=False)