OpenPyXl的使用

作者: TryEnough | 来源:发表于2016-11-28 16:36 被阅读3320次

    翻译自官方文档

    开始在内存中使用

    创建一个workbook

    在刚开始使用openpyxl的时候,不需要直接在文件系统中创建一个文件,仅仅需要导入Workbook类并开始使用它:

    >>> from openpyxl import Workbook
    >>> wb = Workbook()
    

    一个workbook总是会创建至少一个worksheet(工作表),可以通过openpyxl.workbook.Workbook.active()这个属性去获取:

    >>> ws = wb.active
    

    这个函数使用_active_sheet_index这个属性,默认设置的值是0,除非你指定一个值,否则总是获取到第一个worksheet。

    你可以使用openpyxl.workbook.Workbook.create_sheet()来创建一个新的worksheet:

    >>> ws1 = wb.create_sheet("Mysheet") # insert at the end (default)# or
    >>> ws2 = wb.create_sheet("Mysheet", 0) # insert at first position
    

    当创建脚标的时候会自动创建一个名字,按照(Sheet, Sheet1, Sheet2, ...)这个列表名创建,你可以使用tiitle属性来修改这个名字:

    >>> ws.title = "New Title"
    

    一旦给了一个worksheet名字,就可以通过一个key去获取这个worksheet:

    >>> ws3 = wb["New Title"]
    

    你可以使用openpyxl.workbook.Workbook.sheetnames()这个属性获取所有的脚标的名字:

    >>> print(wb.sheetnames)['Sheet2', 'New Title', 'Sheet1']
    

    可以迭代所有的脚标:

    >>> for sheet in wb:
    ...     print(sheet.title)
    

    可以使用openpyxl.workbook.Workbook.copy_worksheet()这个属性复制一个worksheet:

    >>> source = wb.active
    >>> target = wb.copy_worksheet(source)
    

    注意:只有cells 和 styles能够被复制,不能在workbooks之间复制worksheets,你可以在一个workbook中复制worksheets

    玩数据

    获取一个cell

    现在我们已经知道怎么访问一个worksheet,我们可以开始修改cell的内容了。(一个cell就是一个单元格)
    cell可以直接通过key来获取:

    >>> c = ws['A4']
    

    这将会返回一个cell或创建一个不存在的cell。cell 的值可以直接被赋值:

    >>> ws['A4'] = 4
    

    也可以使用另外一个方法openpyxl.worksheet.Worksheet.cell():

    >>> d = ws.cell(row=4, column=2, value=10)
    

    Note:当在内存当中创建一个worksheet的时候,它没有包含任何cell,当它们第一次被访问的时候被创建

    Warning:因为excel表的滚动特性,滚动出来的cell也会被创建出来,即使没有访问那些cell,例如:

    >>> for i in range(1,101):
    ...        for j in range(1,101):
    ...            ws.cell(row=i, column=j)
    

    这将会创建100*100个空的cell

    访问多个cell

    使用切片可以访问多个cell

    >>> cell_range = ws['A1':'C2']
    

    行和列能够被轻松的获取到:

    >>> colC = ws['C']
    >>> col_range = ws['C:D']
    >>> row10 = ws[10]
    >>> row_range = ws[5:10]
    

    也可以使用openpyxl.worksheet.Worksheet.iter_rows()这个方法:

    >>> for row in ws.iter_rows(min_row=1, max_col=3, max_row=2):
    ...         for cell in row:
    ...              print(cell)
    <Cell Sheet1.A1>
    <Cell Sheet1.B1>
    <Cell Sheet1.C1>
    <Cell Sheet1.A2>
    <Cell Sheet1.B2>
    <Cell Sheet1.C2>
    

    相似的方法openpyxl.worksheet.Worksheet.iter_cols()也可以:

    >>> for col in ws.iter_cols(min_row=1, max_col=3, max_row=2):
    ...        for cell in col:
    ...            print(cell)
    <Cell Sheet1.A1>
    <Cell Sheet1.A2>
    <Cell Sheet1.B1>
    <Cell Sheet1.B2>
    <Cell Sheet1.C1>
    <Cell Sheet1.C2>
    

    如果你想迭代一个文件的所有行或列,可以使用openpyxl.worksheet.Worksheet.rows()这个属性:

    >>> ws = wb.active
    >>> ws['C9'] = 'hello world'
    >>> tuple(ws.rows)
    ((<Cell Sheet.A1>, <Cell Sheet.B1>, <Cell Sheet.C1>),
    (<Cell Sheet.A2>, <Cell Sheet.B2>, <Cell Sheet.C2>),
    (<Cell Sheet.A3>, <Cell Sheet.B3>, <Cell Sheet.C3>),
    (<Cell Sheet.A4>, <Cell Sheet.B4>, <Cell Sheet.C4>),
    (<Cell Sheet.A5>, <Cell Sheet.B5>, <Cell Sheet.C5>),
    (<Cell Sheet.A6>, <Cell Sheet.B6>, <Cell Sheet.C6>),
    (<Cell Sheet.A7>, <Cell Sheet.B7>, <Cell Sheet.C7>),
    (<Cell Sheet.A8>, <Cell Sheet.B8>, <Cell Sheet.C8>),
    (<Cell Sheet.A9>, <Cell Sheet.B9>, <Cell Sheet.C9>))
    

    或者openpyxl.worksheet.Worksheet.columns()这个属性:

    >>> tuple(ws.columns)
    ((<Cell Sheet.A1>,
    <Cell Sheet.A2>,
    <Cell Sheet.A3>,
    <Cell Sheet.A4>,
    <Cell Sheet.A5>,
    <Cell Sheet.A6>,
    ...
    <Cell Sheet.B7>,
    <Cell Sheet.B8>,
    <Cell Sheet.B9>),
    (<Cell Sheet.C1>,
    <Cell Sheet.C2>,
    <Cell Sheet.C3>,
    <Cell Sheet.C4>,
    <Cell Sheet.C5>,
    <Cell Sheet.C6>,
    <Cell Sheet.C7>,
    <Cell Sheet.C8>,
    <Cell Sheet.C9>))
    

    数据存储

    一旦我们有了一个openpyxl.cell.Cell,我们就可以给它赋值:

    >>> c.value = 'hello, world'
    >>> print(c.value)'hello, world'
    >>> d.value = 3.14
    >>> print(d.value)3.14
    

    也能使用类型和格式推断:

    >>> wb = Workbook(guess_types=True)
    >>> c.value = '12%'
    >>> print(c.value)
    0.12
    >>> import datetime
    >>> d.value = datetime.datetime.now()
    >>> print d.valuedatetime.datetime(2010, 9, 10, 22, 25, 18)
    >>> c.value = '31.50'
    >>> print(c.value)
    31.5
    
    保存到文件

    最简单和快速的保存一个workbook方法是使用openpyxl.workbook.Workbook模块的openpyxl.workbook.Workbook.save()这个方法:

    >>> wb = Workbook()
    >>> wb.save('balances.xlsx')
    

    Warning:这个方法将会在没有警告提示下覆盖已经有的内容
    可以使用template=True将一个workbook保存成一个模版:

    >>> wb = load_workbook('document.xlsx')
    >>> wb.template = True
    >>> wb.save('document_template.xltx')
    

    或者设置这个属性为false(默认)来保存为一个文件:

    >>> wb = load_workbook('document_template.xltx')
    >>> wb.template = False
    >>> wb.save('document.xlsx', as_template=False)
    

    *Warning:当保存文档的时候在模版文档中你应该注意文档的扩展名(后缀名)和数据描述,否则可能会导致文档不能被再次打开,如下错误式例:

    >>> wb = load_workbook('document.xlsx')
    >>> # 应该保存成扩展名为*.xlsx
    >>> wb.save('new_document.xlsm')
    >>> # Excel软件不能再次打开此文件
    >>>
    >>> # 或者
    >>>
    >>> # 应该指定属性keep_vba=True
    >>> wb = load_workbook('document.xlsm')
    >>> wb.save('new_document.xlsm')
    >>> #  Excel软件不能再次打开此文件
    >>>
    >>> # 或者
    >>>
    >>> wb = load_workbook('document.xltm', keep_vba=True)
    >>> # 如果我们需要一个模版文件,就必须指定扩展名为 *.xltm.
    >>> wb.save('new_document.xlsm')
    >>> #  Excel软件不能再次打开此文件
    
    

    加载一个文件

    类似于写文件,可以导入openpyxl.load_workbook()来打开一个已经存在的workbook:

    >>> from openpyxl import load_workbook
    >>> wb2 = load_workbook('test.xlsx')
    >>> print wb2.get_sheet_names()
    ['Sheet2', 'New Title', 'Sheet1']
    

    基本教程已经完了。接下来是一些使用例子:


    写一个workbook

    >>> from openpyxl import Workbook
    >>> from openpyxl.compat import range
    >>> from openpyxl.utils import get_column_letter
    >>>
    >>> wb = Workbook()
    >>>
    >>> dest_filename = 'empty_book.xlsx'
    >>>
    >>> ws1 = wb.active
    >>> ws1.title = "range names"
    >>>
    >>> for row in range(1, 40):
    ...     ws1.append(range(600))
    >>>
    >>> ws2 = wb.create_sheet(title="Pi")
    >>>
    >>> ws2['F5'] = 3.14
    >>>
    >>> ws3 = wb.create_sheet(title="Data")
    >>> for row in range(10, 20):
    ...     for col in range(27, 54):
    ...         _ = ws3.cell(column=col, row=row, value="{0}".format(get_column_letter(col)))
    >>> print(ws3['AA10'].value)
    AA
    >>> wb.save(filename = dest_filename)
    

    读取一个已经存在的文件

    >>> from openpyxl import load_workbook
    >>> wb = load_workbook(filename = 'empty_book.xlsx')
    >>> sheet_ranges = wb['range names']
    >>> print(sheet_ranges['D18'].value)
    

    警告:openpyxl不能读取Excle中所有的对象,当打开和保存相同名字的文件的时候,图片和图表将会丢失

    使用数字格式:

    >>> import datetime
    >>> from openpyxl import Workbook
    >>> wb = Workbook()
    >>> ws = wb.active
    >>> # set date using a Python datetime
    >>> ws['A1'] = datetime.datetime(2010, 7, 21)
    >>>
    >>> ws['A1'].number_format
    'yyyy-mm-dd h:mm:ss'
    >>> # You can enable type inference on a case-by-case basis
    >>> wb.guess_types = True
    >>> # set percentage using a string followed by the percent sign
    >>> ws['B1'] = '3.14%'
    >>> wb.guess_types = False
    >>> ws['B1'].value
    0.031400000000000004
    >>>
    >>> ws['B1'].number_format
    '0%'
    

    使用公式:

    >>> from openpyxl import Workbook
    >>> wb = Workbook()
    >>> ws = wb.active
    >>> # add a simple formula
    >>> ws["A1"] = "=SUM(1, 1)"
    >>> wb.save("formula.xlsx")
    

    警告:公式必须使用英文名,并且公式的参数必须使用逗号分隔,不能使用其他的符号如分号

    openpyxl从不评估公式,但是可以检查公式的名字:

    >>> from openpyxl.utils import FORMULAE
    >>> "HEX2DEC" in FORMULAE
    True
    

    如果你想使用一个不知道的公式,这可能是因为你使用的公式,没有包括在初始规范。 这样的公式必须以xlfn作为前缀。

    合并/取消合并单元格:

    >>> from openpyxl.workbook import Workbook
    >>>
    >>> wb = Workbook()
    >>> ws = wb.active
    >>>
    >>> ws.merge_cells('A1:B1')
    >>> ws.unmerge_cells('A1:B1')
    >>>
    >>> # or
    >>> ws.merge_cells(start_row=2,start_column=1,end_row=2,end_column=4)
    >>> ws.unmerge_cells(start_row=2,start_column=1,end_row=2,end_column=4)
    

    插入图片:

    >>> from openpyxl import Workbook
    >>> from openpyxl.drawing.image import Image
    >>>
    >>> wb = Workbook()
    >>> ws = wb.active
    >>> ws['A1'] = 'You should see three logos below'
    >>> # create an image
    >>> img = Image('logo.png')
    >>> # add to worksheet and anchor next to cells
    >>> ws.add_image(img, 'A1')
    >>> wb.save('logo.xlsx')
    

    折叠列:

    >>> import openpyxl
    >>> wb = openpyxl.Workbook()
    >>> ws = wb.create_sheet()
    >>> ws.column_dimensions.group('A','D', hidden=True)
    >>> wb.save('group.xlsx')
    

    使用Pandas 和 NumPy

    openpyxl可以配合使用PandasNumPy这两个很受欢迎的库

    NumPy Support
    openpyxl已内置支持NumPy类型float,integer和boolean。 DateTimes支持使用Pandas的时间戳类型。

    openpyxl.utils.dataframe.dataframe_to_rows()方法提供简单的方式使用Pandas 的Dataframes:

    from openpyxl import Workbook
    from openpyxl.utils.dataframe import dataframe_to_rows
    wb = Workbook()
    ws = wb.active
    
    for r in dataframe_to_rows(df, index=True, header=True):
        ws.append(r)
    

    要将数据框转换为突出显示的标题和索引:

    wb = Workbook()
    ws = wb.active
    
    for r in dataframe_to_rows(df, index=True, header=True):
        ws.append(r)
    
    for cell in ws['A'] + ws[1]:
        cell.style = 'Pandas'
    
    wb.save("pandas_openpyxl.xlsx")
    

    如果你只是想转换数据,可以使用只写模式:

    from openpyxl.cell.cell import WriteOnlyCell
    wb = Workbook(write_only=True)
    ws = wb.create_sheet()
    
    cell = WriteOnlyCell(ws)
    cell.style = 'Pandas'
    
     def format_first_row(row, cell):
    
        for c in row:
            cell.value = c
            yield cell
    
    rows = dataframe_to_rows(df)
    first_row = format_first_row(next(rows), cell)
    ws.append(first_row)
    
    for row in rows:
        row = list(row)
        cell.value = row[0]
        row[0] = cell
        ws.append(row)
    
    wb.save("openpyxl_stream.xlsx")
    

    将工作表转换为Dataframe

    要将工作表转换为Dataframe,您可以使用values属性。 如果工作表没有标题或索引,这很容易:

    df = DataFrame(ws.values)
    

    如果工作表有标题或索引,例如Pandas创建的那个,那么需要做更多的工作:

    data = ws.values
    cols = next(data)[1:]
    data = list(data)
    idx = [r[0] for r in data]
    data = (islice(r, 1, None) for r in data)
    df = DataFrame(data, index=idx, columns=cols)
    

    使用过滤和排序

    要添加过滤器,请定义范围,然后添加列和排序条件:

    from openpyxl import Workbook
    
    wb = Workbook()
    ws = wb.active
    
    data = [
        ["Fruit", "Quantity"],
        ["Kiwi", 3],
        ["Grape", 15],
        ["Apple", 3],
        ["Peach", 3],
        ["Pomegranate", 3],
        ["Pear", 3],
        ["Tangerine", 3],
        ["Blueberry", 3],
        ["Mango", 3],
        ["Watermelon", 3],
        ["Blackberry", 3],
        ["Orange", 3],
        ["Raspberry", 3],
        ["Banana", 3]
    ]
    
    for r in data:
        ws.append(r)
    
    ws.auto_filter.ref = "A1:B15"
    ws.auto_filter.add_filter_column(0, ["Kiwi", "Apple", "Mango"])
    ws.auto_filter.add_sort_condition("B2:B15")
    
    wb.save("filtered.xlsx")
    

    这将添加相关的指令到文件,但不会实际过滤或排序。

    注意:文章翻译了一部分openpyxl的官方文档,还有部分内容暂时没有翻译。

    相关文章

      网友评论

      • 骑着气球逛天空:hi 请教一个文档里的问题:
        show my code:
        #!/usr/bin/env python3
        from openpyxl import Workbook
        from openpyxl.utils.dataframe import dataframe_to_rows

        wb = Workbook()
        ws = wb.active
        for r in dataframe_to_rows(df, index=True, header=True):
        ws.append(r)

        for cell in ws['A'] + ws[1]:
        cell.style = 'Pandas'
        wb.save("pandas_openpyxl.xlsx")
        运行报error:
        Traceback (most recent call last):
        File "/home/vin/Python3/openpyxl/pandasdataframes.py", line 7, in <module>
        for r in dataframe_to_rows(df, index=True, header=True):
        NameError: name 'df' is not defined
        我已经确定过了numpy和pandas都用pip3安装过了,但是还是报df这个error!
        这让我很困惑,能帮忙解答一下么?
        Yangli_93:这个提示就是,变量df没有定义

      本文标题:OpenPyXl的使用

      本文链接:https://www.haomeiwen.com/subject/clrbpttx.html