- openpyxl库是基于excel 2010 xlsx/xlsm文件读写的Python库(请找寻xls文件读写的用户去搜寻pandas、
xlrd
和xlwt、pyexcel等库
)。安装openpyxl库: -
# 如果是pip pip install openpyxl # 如果是conda环境 conda install openpyxl
- 创建工作簿和工作表(这是最基本的操作):
-
# 导包 from openpyxl import Workbook # 创建工作簿对象 workbook = Workbook() # 创建当前工作簿下的工作表 ws = workbook.active # 将工作簿保存在本地 workbook.save()
- 接下来只讲解对合并单元格的处理:
- 对合并单元格的处理是在每一个工作表中,每一个工作表是一个表格嘛。即工作簿、工作表、单元格之间的联系:工作簿-->多个工作表,工作表-->是一张表格,包含多个单元格。
- 在上述代码中,我们取名第一个工作表的名称为ws,那么我们清除、插入、合并等操作都是基于这个工作表实现的。
-
from openpyxl import Workbook # 创建工作簿对象 workbook = Workbook() # 创建当前工作簿下的工作表 ws = workbook.active # 也可以创建一个新的工作表(暂不使用) new_sheet = workbook.create_sheet("NewSheet") # 合并单元格 ws.merge_cells("A1:B2") # 合并单元格第二种 start_row, end_row, start_column, end_column = 15, 15, 1, 4 ws.merge_cells(start_row=start_row, end_row=end_row, start_column=start_column, end_column=end_column) # 给合并单元格插入数据,只能通过在合并范围的最左上角单元格中插入数据来实现在合并单元格擦汗如数据的操作 ws.cell(row=start_row, column=start_column).value = value
- 包括设置字体样式等操作
-
# 设置字体样式 font = Font(name='宋体', size=22, color='000000', bold=True) # 设置单元格样式 alignment = Alignment(horizontal='center', vertical='top', wrap_text=True) # 设置边框样式 # 全黑边框 black_border = Border( left=Side(border_style='thin', color='000000'), right=Side(border_style='thin', color='000000'), top=Side(border_style='thin', color='000000'), bottom=Side(border_style='thin', color='000000') ) # 应用字体样式 ws.cell(row=start_row, column=start_column).font = font # 应用单元格样式 ws.cell(row=start_row, column=start_column).alignment = alignment # 添加边框 for row in range(start_row, end_row + 1): for col in range(start_column, end_column + 1): ws.cell(row=row, column=col).border = cell_border
- 但是,如果一个一个的设计样式各种,对每一个插入数据的地方都要进行这些操作是不符合代码复用的操作的,所以我们要尽可能使得代码整洁可读,那怎么做呢,毕竟每一个都要设置起始行、起始列、结束行、结束列、内容、字体格式、单元格格式、边框格式,如果确定只需要这些格式的话,我们把它们全部做成参数传递,会不会更好呢。
- 接下来是对应的一些代码:
-
from io import BytesIO import requests from flask import make_response from openpyxl.workbook import Workbook from openpyxl.styles import Font, Alignment, Border, Side from openpyxl.drawing.image import Image from openpyxl.writer.excel import save_virtual_workbook def get_excel(id: str = None, *args, **kwargs): ''' 下载导出:基本信息填报表 ''' # 创建excel表 # 创建一个新的工作簿 wb = Workbook() # 选择默认的活动工作表 ws = wb.active ws.title = "第1页" # 基本信息填报表: 相关信息 # 执行sql语句获取你的相关信息,自己写一下,result变量接收,通过主键查询,获取单条记录 # 设置字体样式和单元格样式 title_font = Font(name='宋体', size=22, color='000000', bold=True) title_alignment = Alignment(horizontal='center', vertical='top', wrap_text=True) body_font = Font(name='宋体', size=12, color='000000', bold=False) body_alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) # 定义边框样式 # 全黑边框 black_border = Border( left=Side(border_style='thin', color='000000'), right=Side(border_style='thin', color='000000'), top=Side(border_style='thin', color='000000'), bottom=Side(border_style='thin', color='000000') ) # 全无边框 no_border = Border( left=None, right=None, top=None, bottom=None ) # 顶部无边框 top_no_border = Border( left=Side(border_style='thin', color='000000'), right=Side(border_style='thin', color='000000'), top=None, bottom=Side(border_style='thin', color='000000') ) image_path = None merge_cell_params = [] for item in result: # 标题 merge_cell_params.append((1, 1, 1, 15, "基本信息填报表", title_font, title_alignment, black_border)) # 姓名 merge_cell_params.append((3, 5, 1, 2, "姓名", body_font, body_alignment, black_border)) merge_cell_params.append((3, 5, 3, 4, item.name, body_font, body_alignment, black_border)) # 性别 merge_cell_params.append((3, 5, 5, 6, "性别", body_font, body_alignment, black_border)) merge_cell_params.append((3, 5, 7, 8, item.sex, body_font, body_alignment, black_border)) # 出生年月 merge_cell_params.append((3, 4, 9, 10, "出生年月", body_font, body_alignment, black_border)) merge_cell_params.append((3, 4, 11, 12, item.birthYear, body_font, body_alignment, black_border)) # 照片路径 image_path = item.image_path merge_cell_params.append((4, 8, 14, 14, " is image ", body_font, body_alignment, no_border)) # 民族 merge_cell_params.append((6, 6, 1, 2, "民族", body_font, body_alignment, black_border)) merge_cell_params.append((6, 6, 3, 4, item.nation, body_font, body_alignment, black_border)) # 处理合并单元格 for index, params in enumerate(merge_cell_params): start_row, end_row, start_column, end_column, value, font, align, cell_border = params ws.merge_cells(start_row=start_row, end_row=end_row, start_column=start_column, end_column=end_column) # 是否为图片 if value and isinstance(value, str) and "is image" in value: response = requests.get(url=image_path) if response.status_code == 200: # 创建响应对象 image_data = BytesIO(response.content) ws.add_image(image_data, "N4") else: logger.error("未找到照片信息!") else: # 设置值在合并区域的第一个单元格 ws.cell(row=start_row, column=start_column).value = value # ws.cell(row=start_row, column=start_column).value = value if font: # 应用字体样式 ws.cell(row=start_row, column=start_column).font = font if align: # 应用对齐样式 ws.cell(row=start_row, column=start_column).alignment = align # 添加边框 for row in range(start_row, end_row + 1): for col in range(start_column, end_column + 1): ws.cell(row=row, column=col).border = cell_border # 设置行高自适应内容 ws.row_dimensions[start_row].auto_size = True file_name = "测试.xlsx" content = save_virtual_workbook(wb) resp = make_response(content) resp.headers["Content-Disposition"] = 'attachment; filename={}.xlsx'.format(file_name.encode().decode('latin-1')) resp.headers['Content-Type'] = 'application/x-xlsx' return resp
openpyxl库根据模板生成文件api接口返回
于 2024-01-10 09:35:31 首次发布