web-dev-qa-db-ja.com

xlsをxlsxに変換する方法

* .xls(Excel 2003)ファイルがいくつかあります。それらのファイルをxlsx(Excel 2007)に変換したいです。

Uno pythonパッケージを使用して、ドキュメントを保存するときに、フィルター名を設定できます。MSExcel 97しかし、 'MS Excel 2007'のようなフィルター名はありません。

助けてください、xlsをxlsxに変換するフィルター名を設定するにはどうすればよいですか?

22
Thomas

以前にこれをしなければなりませんでした。主なアイデアは、xlrdモジュールを使用してxlsファイルを開いて解析し、openpyxlモジュールを使用してxlsxファイルにコンテンツを書き込むことです。

これが私のコードです。 注意!複雑なxlsファイルを処理できません。使用する場合は、独自の解析ロジックを追加する必要があります。

import xlrd
from openpyxl.workbook import Workbook
from openpyxl.reader.Excel import load_workbook, InvalidFileException

def open_xls_as_xlsx(filename):
    # first open using xlrd
    book = xlrd.open_workbook(filename)
    index = 0
    nrows, ncols = 0, 0
    while nrows * ncols == 0:
        sheet = book.sheet_by_index(index)
        nrows = sheet.nrows
        ncols = sheet.ncols
        index += 1

    # prepare a xlsx sheet
    book1 = Workbook()
    sheet1 = book1.get_active_sheet()

    for row in xrange(0, nrows):
        for col in xrange(0, ncols):
            sheet1.cell(row=row, column=col).value = sheet.cell_value(row, col)

    return book1
17
Ray

マシンにwin32comをインストールする必要があります。ここに私のコードがあります:

import win32com.client as win32
fname = "full+path+to+xls_file"
Excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = Excel.Workbooks.Open(fname)

wb.SaveAs(fname+"x", FileFormat = 51)    #FileFormat = 51 is for .xlsx extension
wb.Close()                               #FileFormat = 56 is for .xls extension
Excel.Application.Quit()
13
kvdogan

フォント、チャート、画像を考慮せずに、私のソリューションは次のとおりです。

$ pip install pyexcel pyexcel-xls pyexcel-xlsx

次に、これを行います::

import pyexcel as p

p.save_book_as(file_name='your-file-in.xls',
               dest_file_name='your-new-file-out.xlsx')

プログラムが必要ない場合は、追加パッケージpyexcel-cliを1つインストールできます。

$ pip install pyexcel-cli
$ pyexcel transcode your-file-in.xls your-new-file-out.xlsx

上記のトランスコーディング手順では、xlrdとopenpyxlを使用します。

12
chfw

ここでは、100%正しい答えは見つかりませんでした。ここにコードを投稿します:

import xlrd
from openpyxl.workbook import Workbook

def cvt_xls_to_xlsx(src_file_path, dst_file_path):
    book_xls = xlrd.open_workbook(src_file_path)
    book_xlsx = Workbook()

    sheet_names = book_xls.sheet_names()
    for sheet_index in range(0,len(sheet_names)):
        sheet_xls = book_xls.sheet_by_name(sheet_names[sheet_index])
        if sheet_index == 0:
            sheet_xlsx = book_xlsx.active()
            sheet_xlsx.title = sheet_names[sheet_index]
        else:
            sheet_xlsx = book_xlsx.create_sheet(title=sheet_names[sheet_index])

        for row in range(0, sheet_xls.nrows):
            for col in range(0, sheet_xls.ncols):
                sheet_xlsx.cell(row = row+1 , column = col+1).value = sheet_xls.cell_value(row, col)

    book_xlsx.save(dst_file_path)
9
Jackypengyu

レイによる答えは私を大いに助けましたが、すべてのシートをxlsからxlsxに変換する簡単な方法を探している人のために、私はこれを作りました Gist

import xlrd
from openpyxl.workbook import Workbook as openpyxlWorkbook

# content is a string containing the file. For example the result of an http.request(url).
# You can also use a filepath by calling "xlrd.open_workbook(filepath)".

xlsBook = xlrd.open_workbook(file_contents=content)
workbook = openpyxlWorkbook()

for i in xrange(0, xlsBook.nsheets):
    xlsSheet = xlsBook.sheet_by_index(i)
    sheet = workbook.active if i == 0 else workbook.create_sheet()
    sheet.title = xlsSheet.name

    for row in xrange(0, xlsSheet.nrows):
        for col in xrange(0, xlsSheet.ncols):
            sheet.cell(row=row, column=col).value = xlsSheet.cell_value(row, col)

# The new xlsx file is in "workbook", without iterators (iter_rows).
# For iteration, use "for row in worksheet.rows:".
# For range iteration, use "for row in worksheet.range("{}:{}".format(startCell, endCell)):".

Xlrd lib here およびopenpyxl here を見つけることができます(たとえば、Google App Engineのプロジェクトでxlrdをダウンロードする必要があります)。

6
Malexandre

私は@ Jackypengyuメソッドのパフォーマンスを改善します

結合されたセルも変換されます。

結果

同じ12個のファイルを同じ順序で変換します。

オリジナル

0:00:01.958159
0:00:02.115891
0:00:02.018643
0:00:02.057803
0:00:01.267079
0:00:01.308073
0:00:01.245989
0:00:01.289295
0:00:01.273805
0:00:01.276003
0:00:01.293834
0:00:01.261401

改善

0:00:00.774101
0:00:00.734749
0:00:00.741434
0:00:00.744491
0:00:00.320796
0:00:00.279045
0:00:00.315829
0:00:00.280769
0:00:00.316380
0:00:00.289196
0:00:00.347819
0:00:00.284242

解決

def cvt_xls_to_xlsx(*args, **kw):
    """Open and convert XLS file to openpyxl.workbook.Workbook object

    @param args: args for xlrd.open_workbook
    @param kw: kwargs for xlrd.open_workbook
    @return: openpyxl.workbook.Workbook


    You need -> from openpyxl.utils.cell import get_column_letter
    """

    book_xls = xlrd.open_workbook(*args, formatting_info=True, ragged_rows=True, **kw)
    book_xlsx = Workbook()

    sheet_names = book_xls.sheet_names()
    for sheet_index in range(len(sheet_names)):
        sheet_xls = book_xls.sheet_by_name(sheet_names[sheet_index])

        if sheet_index == 0:
            sheet_xlsx = book_xlsx.active
            sheet_xlsx.title = sheet_names[sheet_index]
        else:
            sheet_xlsx = book_xlsx.create_sheet(title=sheet_names[sheet_index])

        for crange in sheet_xls.merged_cells:
            rlo, rhi, clo, chi = crange

            sheet_xlsx.merge_cells(
                start_row=rlo + 1, end_row=rhi,
                start_column=clo + 1, end_column=chi,
            )

        def _get_xlrd_cell_value(cell):
            value = cell.value
            if cell.ctype == xlrd.XL_CELL_DATE:
                value = datetime.datetime(*xlrd.xldate_as_Tuple(value, 0))

            return value

        for row in range(sheet_xls.nrows):
            sheet_xlsx.append((
                _get_xlrd_cell_value(cell)
                for cell in sheet_xls.row_slice(row, end_colx=sheet_xls.row_len(row))
            ))

        for rowx in range(sheet_xls.nrows):
            if sheet_xls.rowinfo_map[rowx].hidden != 0:
                print sheet_names[sheet_index], rowx
                sheet_xlsx.row_dimensions[rowx+1].hidden = True
        for coly in range(sheet_xls.ncols):
            if sheet_xls.colinfo_map[coly].hidden != 0:
                print sheet_names[sheet_index], coly
                coly_letter = get_column_letter(coly+1)
                sheet_xlsx.column_dimensions[coly_letter].hidden = True

    return book_xlsx
5
Jhon Anderson

@Jhon Andersonのソリューションを試しましたが、うまく機能しますが、日付のないHH:mm:ssのような時間形式のセルがある場合、「年が範囲外です」というエラーが表示されました。そこでアルゴリズムを再度改善しました。

def xls_to_xlsx(*args, **kw):
"""
    open and convert an XLS file to openpyxl.workbook.Workbook
    ----------
    @param args: args for xlrd.open_workbook
    @param kw: kwargs for xlrd.open_workbook
    @return: openpyxl.workbook.Workbook对象
    """
    book_xls = xlrd.open_workbook(*args, formatting_info=True, ragged_rows=True, **kw)
    book_xlsx = openpyxl.workbook.Workbook()

    sheet_names = book_xls.sheet_names()
    for sheet_index in range(len(sheet_names)):
        sheet_xls = book_xls.sheet_by_name(sheet_names[sheet_index])
        if sheet_index == 0:
            sheet_xlsx = book_xlsx.active
            sheet_xlsx.title = sheet_names[sheet_index]
        else:
            sheet_xlsx = book_xlsx.create_sheet(title=sheet_names[sheet_index])
        for crange in sheet_xls.merged_cells:
            rlo, rhi, clo, chi = crange
            sheet_xlsx.merge_cells(start_row=rlo + 1, end_row=rhi,
            start_column=clo + 1, end_column=chi,)

        def _get_xlrd_cell_value(cell):
            value = cell.value
            if cell.ctype == xlrd.XL_CELL_DATE:
                datetime_tup = xlrd.xldate_as_Tuple(value,0)    
                if datetime_tup[0:3] == (0, 0, 0):   # time format without date
                    value = datetime.time(*datetime_tup[3:])
                else:
                    value = datetime.datetime(*datetime_tup)
            return value

        for row in range(sheet_xls.nrows):
            sheet_xlsx.append((
                _get_xlrd_cell_value(cell)
                for cell in sheet_xls.row_slice(row, end_colx=sheet_xls.row_len(row))
            ))
    return book_xlsx

その後、完璧に動作します!

2
CakeL

シンプルなソリューション

いくつかのxlxxlsx形式に変換する簡単なソリューションが必要でした。ここにはたくさんの答えがありますが、彼らは私が完全に理解していない「魔法」をやっています。

chfw で簡単な解決策が与えられましたが、完全ではありません。

依存関係をインストールする

Pipを使用してインストールする

pip install pyexcel-cli pyexcel-xls pyexcel-xlsx

Execute

すべてのスタイリングとマクロはなくなりますが、情報はそのままです。

単一ファイル用

pyexcel transcode your-file-in.xls your-new-file-out.xlsx

フォルダー内のすべてのファイルに対して、1つのライナー

for file in *.xls; do; echo "Transcoding $file"; pyexcel transcode "$file" "${file}x"; done;
2
Atais

XLSファイルをXLSXに変換

Python3.6を使用して同じ問題に遭遇しましたが、何時間も苦労してffを実行することで解決しましたが、おそらくすべてのパッケージは必要ないでしょう(posslbeと同じくらい明確になります)

続行する前に、次のパッケージをインストールしてください

pip install pyexcel、pip install pyexcel-xls、pip install pyexcel-xlsx、

pip install pyexcel-cli

ステップ1:

import pyexcel

ステップ2: "example.xls"、 "example.xlsx"、 "example.xlsm"

sheet0 = pyexcel.get_sheet(file_name="your_file_path.xls", name_columns_by_row=0)

ステップ3:コンテンツから配列を作成する

xlsarray = sheet.to_array() 

ステップ4:変数の内容を確認して確認する

xlsarray

手順5:(xlsarray)という変数に保持されている配列を(sheet1)という新しいワークブック変数に渡します

sheet1 = pyexcel.Sheet(xlsarray)

手順6:.xlsxで終わる新しいシートを保存します(私の場合はxlsxが必要です)

sheet1.save_as("test.xlsx")
0
lordwilliamsr

Rayからの回答では、データの最初の行と最後の列が切り取られていました。ここに私の修正されたソリューションがあります(python3用):

def open_xls_as_xlsx(filename):
# first open using xlrd
book = xlrd.open_workbook(filename)
index = 0
nrows, ncols = 0, 0
while nrows * ncols == 0:
    sheet = book.sheet_by_index(index)
    nrows = sheet.nrows+1   #bm added +1
    ncols = sheet.ncols+1   #bm added +1
    index += 1

# prepare a xlsx sheet
book1 = Workbook()
sheet1 = book1.get_active_sheet()

for row in range(1, nrows):
    for col in range(1, ncols):
        sheet1.cell(row=row, column=col).value = sheet.cell_value(row-1, col-1) #bm added -1's

return book1
0
benmichae2.

@CaKelおよび@Jhon Andersonソリューション:

def _get_xlrd_cell_value(cell):
    value = cell.value
        if cell.ctype == xlrd.XL_CELL_DATE:
            # Start: if time is 00:00 this fix is necessary
            if value == 1.0:
                datetime_tup = (0, 0, 0)
            else:
            # end
                datetime_tup = xlrd.xldate_as_Tuple(value, 0)

            if datetime_tup[0:3] == (0, 0, 0):
                value = datetime.time(*datetime_tup[3:])
            else:
                value = datetime.datetime(*datetime_tup)
    return value

そして今、このコードは私にとって完璧に動作します!

0
droebi

@Jhonのソリューションを1回試した後、ソリューションとしてpyexcelになりました

pyexcel.save_as(file_name=oldfilename, dest_file_name=newfilename)

PyInstallerでプロジェクトを単一のexeファイルにパッケージ化しようとするまで、正常に機能します。

  File "utils.py", line 27, in __enter__
    pyexcel.save_as(file_name=self.filename, dest_file_name=newfilename)
  File "site-packages\pyexcel\core.py", line 77, in save_as
  File "site-packages\pyexcel\internal\core.py", line 22, in get_sheet_stream
  File "site-packages\pyexcel\plugins\sources\file_input.py", line 39, in get_da
ta
  File "site-packages\pyexcel\plugins\parsers\Excel.py", line 19, in parse_file
  File "site-packages\pyexcel\plugins\parsers\Excel.py", line 40, in _parse_any
  File "site-packages\pyexcel_io\io.py", line 73, in get_data
  File "site-packages\pyexcel_io\io.py", line 91, in _get_data
  File "site-packages\pyexcel_io\io.py", line 188, in load_data
  File "site-packages\pyexcel_io\plugins.py", line 90, in get_a_plugin
  File "site-packages\lml\plugin.py", line 290, in load_me_now
  File "site-packages\pyexcel_io\plugins.py", line 107, in raise_exception
pyexcel_io.exceptions.SupportingPluginAvailableButNotInstalled: Please install p
yexcel-xls
[3192] Failed to execute script

それから、私はパンダに飛びました:

pd.read_Excel(oldfilename).to_Excel(newfilename, sheet_name=self.sheetname,index=False)
0
Xb74Dkjb