如何使用xlsxwriter动态添加格式到现有格式对象

8 投票
4 回答
10480 浏览
提问于 2025-05-01 09:46

在使用xlsxwriter的时候,能不能实时修改或添加已有的格式呢?我希望有这样的功能,这样我就可以保持几个主要的格式,并根据具体情况添加新的格式。

比如在下面的代码中,我想在单元格A2中给dark_blue_header_format添加一个下划线格式。但是,这样做却产生了一些意想不到的结果,如下图所示。我原本期待A1和A3的文字是蓝色,字号24,白色文字;而A2则应该是蓝色,字号24,白色文字,并且带有下划线。

import xlsxwriter

workbook = xlsxwriter.Workbook('demo.xlsx')
worksheet = workbook.add_worksheet()

dark_blue_header_format = workbook.add_format({
    'bg_color': '#5081BB',
    'font_color': '#FFFFFF',
    'font_size': 24
})

worksheet.set_column('A:A', 30)

worksheet.write('A1', 'Company Name', dark_blue_header_format)
worksheet.write('A2', 'Underlined Company Name', dark_blue_header_format.set_underline())
worksheet.write('A3', 'Company Name', dark_blue_header_format)

workbook.close()

这里插入图片描述

我查阅了格式文档,但没有找到可以实时添加格式的内容。如果set_whatever的功能像这个例子那样,那我就不明白它有什么用处了。

如果不能实时给已有格式添加新的格式,那么在创建很多独特格式时,最佳的做法是什么呢?

谢谢!

暂无标签

4 个回答

0

除了使用 copy_format() 这个方法,你还可以利用函数的作用域来清除格式,因为在函数执行完后,格式会被自动删除。

def print_diff_colors(i):
    # generating random color below
    YellowFormat = wb.add_format({'bold':True, 'color':f"#{i}1{i}324"})
    sheet.write_rich_string(i,0 ,
                            'Some ',
                            YellowFormat, 'bold',
                            ' text'
                            )
    
for i in range(10):
    print_diff_colors(i)

这样就能得到动态格式化的单元格:

动态格式化的单元格

不确定你是否还需要这个,但提一下也是值得的。

0

感谢大家关注这个问题。这正是我遇到的情况。使用场景:我想对不同类型的内容应用不同的格式,同时还想对某些单元格应用额外的格式(“高亮”)。比如说,给表格的不同部分添加右边框和/或底边框;用额外的格式来突出显示最大值。

如果一个返回工作簿格式的函数每次都复制格式,我担心在填充一个大表格时会生成太多的格式实例。因此,我实现了一个解决方案,提前生成所有高亮组合的格式。返回格式的函数会从这些预生成的对象中选择一个。我不确定这是否值得分享,因为我对Python还很陌生。

workbook = xlsxwriter.Workbook("test.xlsx")
### example cell formats and highlights
frm_types={
    "norm":   {},
    "it":     {"italic":True},
    "bold":   {"bold":True},
    "boldit": {"bold":True,"italic":True}
            }
frm_highlights={
     "max":           {"bold":True,"font_color":"#006699"},
     "border_right":  {"right":1},
     "border_bottom": {"bottom":1},
     "align_right":   {"align":"right"}
         }
### Creating a table of workbook formats with all highlights combinations 
##  Given:
#    wb - workbook, 
#    frm - format properties as dict, 
#    hlist - list of highlights as dicts.
##  Recursively adds levels to multidim. list - [with no highlight, with highlight],
#     finally returns the last level containing a pair of workbook formats
def frm_hl_level(wb,frm,hlist):
    # create two dicts. of properties: without and with first highlight from hlist
    frm_nohl=copy(frm)
    frm_withhl=copy(frm)
    frm_withhl.update(hlist[0])
    # recursion step
    if len(hlist)==1:
        return [
            wb.add_format(frm_nohl),
            wb.add_format(frm_withhl)    
                ]
    else:
        return[
            frm_hl_level(wb,frm_nohl,hlist[1:]),
            frm_hl_level(wb,frm_withhl,hlist[1:])
                ]
## The formats dictionary: 
#   keys = format names, 
#   items = multidim. tables of corresponding formats with 
#     all highlights combinations
frm_data_dict={
        fnm:
            frm_hl_level( workbook, frm_types[fnm],
                             list(frm_highlights.values()) )
            for fnm in frm_types
        }
## Function which returns workbook format object
## Given 
#   l - list of strings: [1st = format name, rest = highlights names],
#   frms, hls, tbl - format dicts., highlights dicts., dict. of formats tables;
## Returns the corresponding workbook format from the dict. of tables
def frm_select(l,frms=frm_types,hls=frm_highlights,fdt=frm_data_dict):
    # list of highlights keys for identifying table indices
    hl_names=list(hls.keys())
    # list of indices for identifying table element
    ind_l=[0 for _ in hls] # init. - format with no highlights
    # add highlights to index
    for nm in l[1:]:
        ind_l[hl_names.index(nm)]=1
    # access the element of the table
    arr=fdt[l[0]]
    for ind in ind_l:
        arr=arr[ind]
    return arr
12

你可以这样做:

def copy_format(book, fmt):
    properties = [f[4:] for f in dir(fmt) if f[0:4] == 'set_']
    dft_fmt = book.add_format()
    return book.add_format({k : v for k, v in fmt.__dict__.items() if k in properties and dft_fmt.__dict__[k] != v})

workbook = xlsxwriter.Workbook('Test.xlsx')
worksheet = workbook.add_worksheet()

initial_format = workbook.add_format({
    'font_size': 13,
    'bold': 1,
    'border': 1,
    'align': 'center',
})

new_format = copy_format(workbook, initial_format)
new_format.set_font_size(16)
new_format.set_font_color('white')
11

在xlsxwriter中,是否可以实时修改或添加已有的格式?

目前是不可以的。

根据文档的说明:

在XlsxWriter的电子表格中,每种独特的单元格格式都必须有一个对应的格式对象。你不能在使用write()方法时用一个格式,然后再在后面重新定义它。这是因为格式是应用在单元格上的,而不是在它当前的状态,而是在它最终的状态。举个例子:

format = workbook.add_format({'bold': True, 'font_color': 'red'})
worksheet.write('A1', 'Cell A1', format)

# Later...
format.set_font_color('green')
worksheet.write('B1', 'Cell B1', format)

单元格A1最开始被设置为红色字体的格式。但是后来字体颜色被改成了绿色。当Excel显示单元格A1时,它会显示格式的最终状态,在这个例子中就是绿色。

如果你需要创建很多独特的格式,最实用的办法是把这些格式存储在一个字典里,用它们的属性作为索引。

撰写回答