python - 自定义 Ansible 模块 Python XlSXWRITER 无法格式化大于 Z 的行
问题描述
这个 Ansible 模块以 xlsx 格式转换和组合 csv 文件。
我已经复制了模块https://github.com/giovannisciortino/ansible-generate-report
并进行了一些格式更改,例如对齐方式,并且其他模块对于小于宽度小于 Z 的工作表的行工作正常,它会在大于 Z 的列上引发错误,例如 AA AB 。
我们能否添加将 csv 转换为宽度更大的 xlsx 的功能。
我的代码如下:
#!/usr/bin/python
from ansible.module_utils.basic import *
import sys
import os
import csv
import xlsxwriter
import glob
def main():
fields = {
"csv_dir": {"required": True, "type": "str"},
"output_xlsx_file": {"required": True, "type": "str"},
"format_header": {"required": True, "type": "bool"},
# if defined use this csv list as first sheets of the workbook
"summary_csv_list": {"required": False, "type": "list", "default": []},
}
module = AnsibleModule(argument_spec=fields)
wb = xlsxwriter.Workbook(module.params['output_xlsx_file'])
format_header = wb.add_format({'border': 1})
format_header.set_bold()
format_header.set_bg_color('red')
format_header.set_font_color('white')
format_header.set_text_wrap()
format_header.set_align('center')
format_header.set_align('vcenter')
cell_format = wb.add_format({'border': 1})
cell_format.set_center_across('center_across')
cell_format.set_align('left')
cell_format.set_align('vcenter')
csv_dir = module.params['csv_dir']
csv_file_list = sorted(glob.glob(csv_dir + '/*.csv'))
for summary_filename_csv in reversed(module.params['summary_csv_list']):
summary_filename = csv_file_list.index(csv_dir + '/' + summary_filename_csv)
csv_file_list.insert(0, csv_file_list.pop(summary_filename))
for csv_file_path in csv_file_list:
sheet_title = os.path.splitext(os.path.basename(csv_file_path))[0][0:31]
ws = wb.add_worksheet(sheet_title)
with open(csv_file_path, 'r') as csvfile:
table = csv.reader(csvfile)
num_row = 0
num_cols = 0
columns_width = []
for row in table:
if module.params['format_header'] and num_row == 0:
ws.write_row(num_row, 0, row, format_header)
else:
ws.write_row(num_row, 0, row, cell_format)
num_row += 1
num_cols = max(num_cols, len(row))
columns_width = [max(len(j), columns_width[i] if len(columns_width) > i else 1) for i, j in enumerate(row)]
# Simulate autofit column
for i, j in enumerate(columns_width):
column_name = "%s:%s" % (chr(ord('A') + i), chr(ord('A') + i))
ws.set_column(column_name, j)
if module.params['format_header']:
ws.autofilter(0, 0, num_row-1, num_cols-1)
wb.close()
response = {"result": "file %s created" % (module.params['output_xlsx_file'])}
module.exit_json(changed=False, meta=response)
if __name__ == '__main__':
main()
宽度较大的纸张上的 Ansible 错误,如 columa AA AB
任务 [生成报告] ************************************************ *********** 任务执行过程中出现异常。要查看完整的回溯,请使用 -vvv。错误是:AttributeError:“NoneType”对象没有属性“组”致命:[localhost]:失败!=> {"changed": false, "module_stderr": "Traceback (last last last call):\n File "/root/.ansible/tmp/ansible-tmp-1603338799.11-110921-229302004092192/AnsiballZ_xlswriter.py", line 102,在 \n _ansiballz_main()\n 文件“/root/.ansible/tmp/ansible-tmp-1603338799.11-110921-229302004092192/AnsiballZ_xlswriter.py”中,第 94 行,在 _ansiballz_main\n 调用模块(zipped_mod,temp_path,ANSIBALLZ_PARAMS) \n 文件“/root/.ansible/tmp/ansible-tmp-1603338799.11-110921-229302004092192/AnsiballZ_xlswriter.py”,第 40 行,主要的', alter_sys=True)\n 文件 "/usr/lib64/python2.7/runpy.py", 第 176 行, 在 run_module\n fname, loader, pkg_name)\n 文件 "/usr/lib64/python2.7/ runpy.py",第 82 行,在 _run_module_code\n mod_name、mod_fname、mod_loader、pkg_name)\n 文件 "/usr/lib64/python2.7/runpy.py",第 72 行,在 _run_code\n 执行代码在 run_globals\ n 文件“/tmp/ansible_xlswriter_payload_TOQ4f5/ansible_xlswriter_payload.zip/ansible/modules/xlswriter.py”,第 77 行,\n 文件“/tmp/ansible_xlswriter_payload_TOQ4f5/ansible_xlswriter_payload.zip/ansible/modules/xlswriter.py”,第 65 行,在 main\n 文件“/usr/lib/python2.7/site-packages/xlsxwriter/worksheet.py”中,第 120 行,在 column_wrapper\n _, col_1 = xl_cell_to_rowcol(cell_1)\n 文件“/usr/lib/ python2.7/site-packages/xlsxwriter/utility.py”,第 121 行,在 xl_cell_to_rowcol\n col_str = match.group(2)\nAttributeError: 'NoneType' object has no attribute 'group'\n", "module_stdout": "", "msg": "MODULE FAILURE\n有关确切的错误”,“rc”:1} ...忽略
解决方案
这部分代码的逻辑只适用于'A'到'Z':
for i, j in enumerate(columns_width):
column_name = "%s:%s" % (chr(ord('A') + i), chr(ord('A') + i))
ws.set_column(column_name, j)
而不是试图计算出像使用符号而不是符号更简单的范围(请AA:AA
参阅Cell Notation 上的 XlsxWriter 文档):set_column()
(row, col)
A1
for i, j in enumerate(columns_width):
ws.set_column(i, i, j)
推荐阅读
- maven - 使用 Maven 解决库冲突
- python - 带有弹出窗口的pywinauto
- javascript - 即使我定义了宽度和高度,边距自动也不起作用
- python - 如何从 python 运行 Windows PowerShell 脚本?
- python - selenium chromedriver headless 不起作用 python
- matlab - 将 wav 文件转换为没有标头的原始二进制文件
- python - 如何对 Nd 张量进行切片和求和?
- python - 将列转换为行 pandas
- c# - 在 .NET 5 中排除新的 System.Range
- python - Python条件语句逻辑