python中openpyxl和xlsxwriter对Excel的操作方法


Posted in Python onMarch 01, 2021

前几天,项目中有个小需求:提供Excel的上传下载功能,使用模块:openpyxlxlsxwriter,这里简单记录一下。

1.简介

Python中操作Excel的库非常多,为开发者提供了多种选择,如:xlrdxlwtxlutilsxlwingspandaswin32comopenpyxlxlsxwriter等等。
其中:

前三个一般混合使用,对Excel读写操作,适合旧版Excel,仅支持 xls 文件;

  • win32com 库功能丰富,性能强大,适用于Windows;
  • xlwings稍次于前者,但同样功能丰富;pandas适合处理大量数据;
  • xlsxwriter 适合大量数据的写操作,支持图片/表格/图表/筛选/格式/公式等;
  • openpyxl 读写均可,简单易用,功能广泛,可插入图表等,类似前者。

以下主要描述一下后两种(openpyxlxlsxwriter)的简单使用

2.Excel库的使用

2.1.目标

python中openpyxl和xlsxwriter对Excel的操作方法

2.2.openpyxl的使用

2.2.1.安装

pip install openpyxl

2.2.2.写入Excel

import os
from openpyxl import Workbook
from openpyxl.styles import Alignment, Font, colors, PatternFill
from openpyxl.utils import get_column_letter

FILE_PATH = os.path.join(os.path.dirname(__file__), 'files/')


def write_test():
  wb = Workbook()
  filename = FILE_PATH + '/openpyxl_test.xlsx'
  # 活动sheet
  ws1 = wb.active
  ws1.title = "Test-1"

  # 列表追加
  for row in range(1, 10):
    ws1.append(range(9))
  # 创建sheet
  ws2 = wb.create_sheet(title="Test-2")
  # 合并单元格
  ws2.merge_cells('F5:I5')
  # 拆分
  # ws2.unmerge_cells('F5:I5')
  # 单元赋值
  ws2['F5'] = 'hello world'
  # 居中
  ws2['F5'].alignment = Alignment(horizontal='center', vertical='center')
  # sheet标签颜色
  ws2.sheet_properties.tabColor = '1072BA'
  # 字体样式
  bold_itatic_12_font = Font(name='仿宋', size=12, italic=True, color=BLUE, bold=True)
  ws2['F5'].font = bold_itatic_12_font
  # 背景颜色
  bg_color = PatternFill('solid', fgColor='1874CD')
  ws2['F5'].fill = bg_color
  # 行高列宽
  ws2.row_dimensions[5].height = 40 # 第 5 行
  ws2.column_dimensions['F'].width = 30 # F 列

  ws3 = wb.create_sheet(title="Test-3")
  for row in range(10, 20):
    for col in range(10, 20):
      ws3.cell(column=col, row=row, value="0}".format(get_column_letter(col)))
  print(ws3['S10'].value)
  # 保存
  wb.save(filename)

2.2.3.读取Excel

from openpyxl import load_workbook


def read_test(filename):
  wb = load_workbook(filename)

  print('取得所有工作表的表名 :')
  print(wb.sheetnames, '\n')

  print('取得某张工作表 :')
  # sheet = wb['Sheet1']
  # sheet = wb.worksheets[0]
  sheet = wb[wb.sheetnames[0]]
  print(type(sheet))
  print('表名: ' + sheet.title, '\n')

  print('取得活动工作表 :')
  active_sheet = wb.active
  print('表名: ' + active_sheet.title, '\n')

  print('获取工作表的大小:')
  print('总行数: ' + str(active_sheet.max_row))
  print('总列数: ' + str(active_sheet.max_column))

  print('\n获取单元格数据:')
  for row in range(sheet.max_row):
    for col in range(sheet.max_column):
      print(f"第 {row + 1} 行 {col + 1} 列:", sheet.cell(row=row + 1, column=col + 1).value)

  print('\n获取行数据:')
  for i, cell_object in enumerate(list(sheet.rows)):
    cell_lst = [cell.value for cell in cell_object]
    print(f'第 {i + 1} 行:', cell_lst)

2.2.4.案例demo 数据源格式

# contents数据
contents=[
	{
   "uid": "1281948912",
   "group_name": "测试群-5",
   "domain": "ddos5.www.cn",
   "user_area": [
    {
     "num": 1024,
     "region": "中国",
     "percent": 33.33
    },
    {
     "num": 1022,
     "region": "中国香港",
     "percent": 33.33
    },
    {
     "num": 1021,
     "region": "新加坡", 
     "percent": 33.33
    }
   ],
   "gf_area": [
    {
     "num": 5680,
     "region": "中国香港",
     "percent": 97.8
    },
    {
     "num": 60,
     "region": "新加坡",
     "percent": 0.8
    },
    {
     "num": 55,
     "region": "美西",
     "percent": 0.8
    }
   ],
   "sip_area": {
    "waf_ip":["aliyunwaf.com.cn"],
    "sip":["13.75.120.253","18.163.46.57"],
    "isp_region":[
     {
      "country": "中国香港",
      "isp": "microsoft.com"
     },
     {
      "country": "中国香港",
      "isp": "amazon.com"
     }
    ]
   }
  },
]

写入Excel

import os
import time

from openpyxl import Workbook, load_workbook
from openpyxl.styles import Alignment, Font, colors, PatternFill

FILE_PATH = os.path.join(os.path.dirname(__file__), 'files/')
# 颜色
BLACK = colors.COLOR_INDEX[0]
WHITE = colors.COLOR_INDEX[1]
RED = colors.COLOR_INDEX[2]
DARKRED = colors.COLOR_INDEX[8]
BLUE = colors.COLOR_INDEX[4]
DARKBLUE = colors.COLOR_INDEX[12]
GREEN = colors.COLOR_INDEX[3]
DARKGREEN = colors.COLOR_INDEX[9]
YELLOW = colors.COLOR_INDEX[5]
DARKYELLOW = colors.COLOR_INDEX[19]


def export_gf_excel_test(filename=None, sheetName=None, contents=None):
  filename = filename if filename else 'openpyxl_Test.xlsx'
  sheetName = sheetName if sheetName else '测试'
  contents = contents if contents else []
  # 新建工作簿
  wb = Workbook()
  ws = wb.worksheets[0]
  # 设置sheet名称
  ws.title = sheetName
  # sheet标签颜色
  ws.sheet_properties.tabColor = '1072BA'
  # 居中
  pos_center = Alignment(horizontal='center', vertical='center')
  # 字体样式
  bold_12_font = Font(name='仿宋', size=12, italic=False,
            color=BLACK, bold=True)
  # 背景颜色
  bg_color = PatternFill('solid', fgColor='4DCFF6')

  # 设置标题
  # 合并
  merge_lst = [
    'A1:A3', 'B1:B3', 'C1:C3', 'D1:R1', 'S1:AA1', 'AB1:AE1',
    'D2:F2', 'G2:I2', 'J2:L2', 'M2:O2', 'P2:R2', 'S2:U2', 'V2:X2',
    'Y2:AA2', 'AB2:AB3', 'AC2:AC3', 'AD2:AD3', 'AE2:AE3'
  ]
  [ws.merge_cells(c) for c in merge_lst]
  # 填充字段
  title_dic = {
    'A1': 'UID', 'B1': '钉钉群', 'C1': '域名',
    'D1': '用户区域', 'S1': '高防区域', 'AB1': '源站区域',
    'D2': 'TOP1', 'G2': 'TOP2', 'J2': 'TOP3', 'M2': 'TOP4', 'P2': 'TOP5',
    'S2': 'TOP1', 'V2': 'TOP2', 'Y2': 'TOP3',
    'AB2': 'WAF IP', 'AC2': '源站IP', 'AD2': '源站IP区域', 'AE2': '运营商'
  }
  line3_v = ['物理区域', '请求量', '占比'] * 8
  line3_k = [chr(i) + '3' for i in range(68, 91)] + ['AA3']
  title_dic.update(dict(zip(line3_k, line3_v)))
  for k, v in title_dic.items():
    ws[k].value = v
    ws[k].font = bold_12_font
    ws[k].alignment = pos_center
    ws[k].fill = bg_color

  # 列宽
  width_dic = {
    'A': 30, 'B': 30, 'C': 30,
    'AB': 16, 'AC': 16, 'AD': 16, 'AE': 16
  }
  for k, v in width_dic.items():
    ws.column_dimensions[k].width = v

  # 内容
  for i, dic in enumerate(contents):
    user_gf_mod = {'region': '', 'num': '', 'percent': ''}
    user_area = dic['user_area']
    gf_area = dic['gf_area']
    sip_area = dic['sip_area']
    # UID+域名
    data = [dic['uid'], dic['group_name'], dic['domain']]
    # 用户区域
    if not user_area:
      user_area = [user_gf_mod] * 5
    else:
      user_area = list(
        map(lambda item: {
          'region': item['region'], 'num': item['num'], 'percent': item['percent']}, user_area)
      )
      [user_area.append(user_gf_mod) for _ in range(5 - len(user_area))]
    [data.extend(user_area[u].values()) for u in range(len(user_area))]
    # 高防区域
    if not gf_area:
      gf_area = [user_gf_mod] * 3
    else:
      gf_area = list(
        map(lambda item: {
          'region': item['region'], 'num': item['num'], 'percent': item['percent']}, gf_area)
      )
      [gf_area.append(user_gf_mod) for _ in range(3 - len(gf_area))]
    [data.extend(gf_area[g].values()) for g in range(len(gf_area))]
    # 源站区域
    waf_ip = sip_area['waf_ip']
    sip = sip_area['sip']
    isp_region = sip_area['isp_region']
    data.append(','.join(waf_ip)) if waf_ip else data.append('')
    data.append(','.join(sip)) if sip else data.append('')
    if not isp_region:
      data.extend([''] * 2)
    else:
      try:
        country = ','.join(map(lambda item: item['country'], isp_region))
        isp = ','.join(map(lambda item: item['isp'] if item['isp'] else '暂未查到', isp_region))
        data.append(country)
        data.append(isp)
      except Exception as e:
        print(e)
        print(isp_region)

    # 写入Excel
    ws.append(data)

  # 保存文件
  wb.save(filename=filename)


if __name__ == "__main__":
	curTime = ''.join(map(lambda i: str(i) if len(str(i)) >= 2 else '%02d' % i, [i for i in time.localtime()[:-4]]))
  filename = os.path.join(FILE_PATH, 'openpyxl_Test_{}.xlsx'.format(curTime))
  export_gf_excel_test(filename, contents=contents)

2.3.xlsxwriter的使用

2.3.1.安装

pip install XlsxWriter

2.3.2.写入Excel

import os
import time
import json

import xlsxwriter

FILE_PATH = os.path.join(os.path.dirname(__file__), 'files/')


def export_gf_excel_test(filename=None, sheetName=None, contents=None):
  filename = filename if filename else 'xlsxwriter_Test.xlsx'
  sheetName = sheetName if sheetName else '测试'
  contents = contents if contents else []
  # 新建
  wb = xlsxwriter.Workbook(filename)
  ws = wb.add_worksheet(name=sheetName)
  # 设置风格
  style1 = wb.add_format({
    "bold": True,
    'font_name': '仿宋',
    'font_size': 12,
    # 'font_color': '#217346',
    'bg_color': '#4DCFF6',
    "align": 'center',
    "valign": 'vcenter',
    'text_wrap': 1
  })
  style2 = wb.add_format({
    # "bold": True,
    # 'font_name': '仿宋',
    'font_size': 11,
    'font_color': '#217346',
    'bg_color': '#E6EDEC',
    "align": 'center',
    "valign": 'vcenter',
    # 'text_wrap': 1
  })

  # 标题
  ws.set_column('A1:AE1', None, style1)
  # 合并单元格: first_row, first_col, last_row, last_col
  # 第 1 行
  ws.merge_range(0, 0, 2, 0, 'UID')
  ws.merge_range(0, 1, 2, 1, '钉钉群')
  ws.merge_range(0, 2, 2, 2, '域名')
  ws.merge_range(0, 3, 0, 17, '用户区域')
  ws.merge_range(0, 18, 0, 26, '高防区域')
  ws.merge_range(0, 27, 0, 30, '源站区域')
  # 第 2 行
  user_tl2 = ['TOP' + str(i) for i in range(1, 6)]
  gf_tl2 = user_tl2[:3]
  [ws.merge_range(1, 3 * (i + 1), 1, 3 * (i + 2) - 1, name) for i, name in enumerate(user_tl2 + gf_tl2)]
  # 第 3 行
  user_gf_tl3 = ['物理区域', '请求量', '占比'] * 8
  sip_tl3 = ['WAF IP', '源站IP', '源站IP区域', '运营商']
  [ws.write(2, 3 + i, name) for i, name in enumerate(user_gf_tl3)]
  [ws.merge_range(1, 27 + i, 2, 27 + i, name) for i, name in enumerate(sip_tl3)]

  # ws.write(11, 2, '=SUM(1:10)') # 增加公式
  # ws.set_default_row(35) # 设置默认行高
  # 设置列宽
  ws.set_column(0, 2, 30)
  ws.set_column(3, 26, 10)
  ws.set_column(27, 30, 16)

  # 内容
  for i, dic in enumerate(contents):
    user_gf_mod = {'region': '', 'num': '', 'percent': ''}
    user_area = dic['user_area']
    gf_area = dic['gf_area']
    sip_area = dic['sip_area']
    # UID+域名
    data = [dic['uid'], dic['group_name'], dic['domain']]
    # 用户区域
    if not user_area:
      user_area = [user_gf_mod] * 5
    else:
      user_area = list(
        map(lambda item: {
          'region': item['region'], 'num': item['num'], 'percent': item['percent']}, user_area)
      )
      [user_area.append(user_gf_mod) for _ in range(5 - len(user_area))]
    [data.extend(user_area[u].values()) for u in range(len(user_area))]
    # 高防区域
    if not gf_area:
      gf_area = [user_gf_mod] * 3
    else:
      gf_area = list(
        map(lambda item: {
          'region': item['region'], 'num': item['num'], 'percent': item['percent']}, gf_area)
      )
      [gf_area.append(user_gf_mod) for _ in range(3 - len(gf_area))]
    [data.extend(gf_area[g].values()) for g in range(len(gf_area))]
    # 源站区域
    waf_ip = sip_area['waf_ip']
    sip = sip_area['sip']
    isp_region = sip_area['isp_region']
    data.append(','.join(waf_ip)) if waf_ip else data.append('')
    data.append(','.join(sip)) if sip else data.append('')
    if not isp_region:
      data.extend([''] * 2)
    else:
      try:
        country = ','.join(map(lambda item: item['country'], isp_region))
        isp = ','.join(map(lambda item: item['isp'] if item['isp'] else '暂未查到', isp_region))
        data.append(country)
        data.append(isp)
      except Exception as e:
        print(e)
        print(isp_region)

    # 写入Excel
    ws.write_row('A' + str(i + 4), data, style2)

  # 保存关闭文件
  wb.close()


if __name__ == '__main__':
	curTime = ''.join(map(lambda i: str(i) if len(str(i)) >= 2 else '%02d' % i, [i for i in time.localtime()[:-4]]))
  filename = os.path.join(FILE_PATH, 'xlsxwriter_Test_{}.xlsx'.format(curTime))
  export_gf_excel_test(filename, contents=contents)

以上是两个库操作Excel的简单实现。对于一些复杂需求的处理,可以查看相关文档。

到此这篇关于python中openpyxl和xlsxwriter对Excel的操作方法的文章就介绍到这了,更多相关python openpyxl和xlsxwriter对Excel操作内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python中global与nonlocal比较
Nov 21 Python
Python实现获取邮箱内容并解析的方法示例
Jun 16 Python
基于DataFrame改变列类型的方法
Jul 25 Python
Django+JS 实现点击头像即可更改头像的方法示例
Dec 26 Python
python Dijkstra算法实现最短路径问题的方法
Sep 19 Python
Python Process多进程实现过程
Oct 22 Python
Django框架模板用法入门教程
Nov 04 Python
使用python切片实现二维数组复制示例
Nov 26 Python
Jupyter Notebook 文件默认目录的查看以及更改步骤
Apr 14 Python
Pytorch 使用CNN图像分类的实现
Jun 16 Python
Pandas加速代码之避免使用for循环
May 30 Python
python实现对doc、txt、xls等文档的读写操作
Apr 02 Python
python中random模块详解
Mar 01 #Python
利用python实现汉诺塔游戏
Mar 01 #Python
python绘制汉诺塔
Mar 01 #Python
彻底解决pip下载pytorch慢的问题方法
Mar 01 #Python
Python 里最强的地图绘制神器
Mar 01 #Python
Python的collections模块真的很好用
Mar 01 #Python
Python  Asyncio模块实现的生产消费者模型的方法
Mar 01 #Python
You might like
PHP制作图型计数器的例子
2006/10/09 PHP
php adodb操作mysql数据库
2009/03/19 PHP
PHP与javascript实现变量交互的示例代码
2013/07/23 PHP
php去除换行(回车换行)的三种方法
2014/03/26 PHP
PHP语法自动检查的Vim插件
2014/08/11 PHP
Yii2框架操作数据库的方法分析【以mysql为例】
2019/05/27 PHP
“不能执行已释放的Script代码”错误的原因及解决办法
2007/09/09 Javascript
jquery pagination插件实现无刷新分页代码
2009/10/13 Javascript
这段js代码得节约你多少时间
2011/12/20 Javascript
javascript获取dom的下一个节点方法
2014/09/05 Javascript
javascript中hasOwnProperty() 方法使用指南
2015/03/09 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
原生JS取代一些JQuery方法的简单实现
2016/09/20 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
浅谈AngularJs指令之scope属性详解
2016/10/24 Javascript
Vue概念及常见命令介绍(1)
2016/12/08 Javascript
微信小程序实现图片懒加载的示例代码
2017/12/13 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
Nautil 中使用双向数据绑定的实现
2019/10/02 Javascript
js实现录音上传功能
2019/11/22 Javascript
toString.call()通用的判断数据类型方法示例
2020/08/28 Javascript
Python实现的二维码生成小软件
2014/07/11 Python
python中map、any、all函数用法分析
2015/04/21 Python
Python中IPYTHON入门实例
2015/05/11 Python
浅析Python中的join()方法的使用
2015/05/19 Python
python基于phantomjs实现导入图片
2016/05/13 Python
Django框架模板注入操作示例【变量传递到模板】
2018/12/19 Python
python求平均数、方差、中位数的例子
2019/08/22 Python
allbeauty美国:英国在线美容店
2019/03/11 全球购物
护士在校生自荐信
2014/02/01 职场文书
环境建设实施方案
2014/03/14 职场文书
我的大学生活演讲稿
2014/04/25 职场文书
老公保证书范文
2014/04/29 职场文书
员工教育培训协议书
2014/09/27 职场文书
MySQL示例讲解数据库约束以及表的设计
2022/06/16 MySQL
win server2012 r2服务器共享文件夹如何设置
2022/06/21 Servers