openpyxl库根据模板生成文件api接口返回

  • 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

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缱绻命运

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值