web-dev-qa-db-ja.com

openpyxl-列幅のサイズを調整します

CSVファイルをXLSXファイルに変換する次のスクリプトがありますが、列サイズが非常に狭いです。データを読み取るためにマウスでドラッグする必要があるたびに。 openpyxlで列幅を設定する方法を知っている人はいますか?

これが私が使用しているコードです。

#!/usr/bin/python2.6
import csv
from openpyxl import Workbook
from openpyxl.cell import get_column_letter

f = open('users_info_cvs.txt', "rU")

csv.register_dialect('colons', delimiter=':')

reader = csv.reader(f, dialect='colons')

wb = Workbook()
dest_filename = r"account_info.xlsx"

ws = wb.worksheets[0]
ws.title = "Users Account Information"

for row_index, row in enumerate(reader):
    for column_index, cell in enumerate(row):
        column_letter = get_column_letter((column_index + 1))
        ws.cell('%s%s'%(column_letter, (row_index + 1))).value = cell

wb.save(filename = dest_filename)
48
Satish

これを推定する(またはモノラル幅のフォントを使用する)ことができます。データが[['' a1 '、' a2 ']、[' b1 '、' b2 ']]のようなネストされた配列であると仮定しましょう

各列の最大文字数を取得できます。次に、幅をそれに設定します。幅は、モノスペースフォントの幅とまったく同じです(少なくとも他のスタイルを変更しない場合)。可変幅フォントを使用している場合でも、それはまともな見積もりです。これは数式では機能しません。

column_widths = []
for row in data:
    for i, cell in enumerate(row):
        if len(column_widths) > i:
            if len(cell) > column_widths[i]:
                column_widths[i] = len(cell)
        else:
            column_widths += [len(cell)]

for i, column_width in enumerate(column_widths):
    worksheet.column_dimensions[get_column_letter(i+1)].width = column_width

ちょっとしたハックですが、レポートはより読みやすくなります。

64
Bufke

ブフケの答えの私のバリエーション。配列との分岐を少し避け、空のセル/列を無視します。

非文字列セル値の修正。

ws = your current worksheet
dims = {}
for row in ws.rows:
    for cell in row:
        if cell.value:
            dims[cell.column] = max((dims.get(cell.column, 0), len(str(cell.value))))    
for col, value in dims.items():
    ws.column_dimensions[col].width = value
32
velis

少なくともopenpyxlバージョン2.4.0で機能するすべての列の幅を設定するためのさらにPython的な方法:

for column_cells in worksheet.columns:
    length = max(len(as_text(cell.value)) for cell in column_cells)
    worksheet.column_dimensions[column_cells[0].column].width = length

As_text関数は、Python 3のように、値を適切な長さの文字列に変換するものでなければなりません。

def as_text(value):
    if value is None:
        return ""
    return str(value)
27
User3759685

Merged_cellsに問題があり、自動サイズ調整が正しく機能しません。同じ問題がある場合は、次のコードで解決できます。

for col in worksheet.columns:
    max_length = 0
    column = col[0].column # Get the column name
    for cell in col:
        if cell.coordinate in worksheet.merged_cells: # not check merge_cells
            continue
        try: # Necessary to avoid error on empty cells
            if len(str(cell.value)) > max_length:
                max_length = len(cell.value)
        except:
            pass
    adjusted_width = (max_length + 2) * 1.2
    worksheet.column_dimensions[column].width = adjusted_width
6
Virako

上記の受け入れられた答えのわずかな改善、私はよりPython的だと思う(許しを求めるのは許可を求めるよりも良い)

column_widths = []
for row in workSheet.iter_rows():
    for i, cell in enumerate(row):
        try:
            column_widths[i] = max(column_widths[i], len(cell.value))
        except IndexError:
            column_widths.append(len(cell.value))

for i, column_width in enumerate(column_widths):
    workSheet.column_dimensions[get_column_letter(i + 1)].width = column_width
3
shayst

Openpxylが更新されたときに、これに対する回答の@ User3759685を変更する必要がありました。エラーが発生していました。よく@phihagもコメントでこれを報告しました

for column_cells in ws.columns:
    new_column_length = max(len(as_text(cell.value)) for cell in column_cells)
    new_column_letter = (openpyxl.utils.get_column_letter(column_cells[0].column))
    if new_column_length > 0:
        ws.column_dimensions[new_column_letter].width = new_column_length + 1
1
Monte Jones

数値をASCII値に変換し、column_dimensionパラメーターに渡すことができます

import openpyxl as xl

work_book = xl.load_workbook('file_location')
sheet = work_book['Sheet1']
column_number = 2
column = str(chr(64 + column_number))
sheet.column_dimensions[column].width = 20
work_book.save('file_location')
1
Prashant Tiwari

これは@Virakoのコードスニペットを参照する私のバージョンです

def adjust_column_width_from_col(ws, min_row, min_col, max_col):

        column_widths = []

        for i, col in \
                enumerate(
                    ws.iter_cols(min_col=min_col, max_col=max_col, min_row=min_row)
                ):

            for cell in col:
                value = cell.value
                if value is not None:

                    if isinstance(value, str) is False:
                        value = str(value)

                    try:
                        column_widths[i] = max(column_widths[i], len(value))
                    except IndexError:
                        column_widths.append(len(value))

        for i, width in enumerate(column_widths):

            col_name = get_column_letter(min_col + i)
            value = column_widths[i] + 2
            ws.column_dimensions[col_name].width = value

そして、使い方は以下の通りです、

adjust_column_width_from_col(ws, 1,1, ws.max_column)
1
alones

上記のすべての答えは、col [0] .columnが数値を返し、worksheet.column_dimensions [column]が列の代わりに 'A'、 'B'、 'C​​'などの文字のみを受け入れるという問題を生成しています。 @Virakoのコードを変更しましたが、現在は正常に機能しています。

import re
import openpyxl
..
for col in _ws.columns:
    max_lenght = 0
    print(col[0])
    col_name = re.findall('\w\d', str(col[0]))
    col_name = col_name[0]
    col_name = re.findall('\w', str(col_name))[0]
    print(col_name)
    for cell in col:
        try:
            if len(str(cell.value)) > max_lenght:
                max_lenght = len(cell.value)
        except:
            pass
    adjusted_width = (max_lenght+2)
    _ws.column_dimensions[col_name].width = adjusted_width
1
Ssubrat Rrudra