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使用matplotlib绘制动画的方法
May 20 Python
Python爬取网易云音乐上评论火爆的歌曲
Jan 19 Python
在windows下Python打印彩色字体的方法
May 15 Python
python3实现windows下同名进程监控
Jun 21 Python
Python图片转换成矩阵,矩阵数据转换成图片的实例
Jul 02 Python
python对html过滤处理的方法
Oct 21 Python
python整合ffmpeg实现视频文件的批量转换
May 31 Python
使用 python pyautogui实现鼠标键盘控制功能
Aug 04 Python
python编程进阶之类和对象用法实例分析
Feb 21 Python
python脚本和网页有何区别
Jul 02 Python
Python实现自动装机功能案例分析
Oct 22 Python
Jupyter notebook 更改文件打开的默认路径操作
May 21 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
什么是短波收听SWL
2021/03/01 无线电
优化使用mysql存储session的php代码
2008/01/10 PHP
php日历[测试通过]
2008/03/27 PHP
php数组函数序列之sort() 对数组的元素值进行升序排序
2011/11/02 PHP
C#静态方法与非静态方法实例分析
2014/09/22 PHP
php实现图片按比例截取的方法
2017/02/06 PHP
php学习笔记之mb_strstr的基本使用
2018/02/03 PHP
Laravel框架实现的记录SQL日志功能示例
2018/06/19 PHP
用正则表达式 动态创建/增加css style script 兼容IE firefox
2009/03/10 Javascript
ajax请求乱码的解决方法(中文乱码)
2014/04/10 Javascript
jQuery取id有.的值的方法
2014/05/21 Javascript
js实现3D图片逐张轮播幻灯片特效代码分享
2015/09/09 Javascript
微信开发 微信授权详解
2016/10/21 Javascript
js实现的简练高效拖拽功能示例
2016/12/21 Javascript
详解vue-router 2.0 常用基础知识点之router.push()
2017/05/10 Javascript
Angular客户端请求Rest服务跨域问题的解决方法
2017/09/19 Javascript
Es6 Generator函数详细解析
2018/02/24 Javascript
详解Require.js与Sea.js的区别
2018/08/05 Javascript
Vue中CSS动画原理的实现
2019/02/13 Javascript
layui自定义验证,用ajax查询后台是否有重复数据,form.verify的例子
2019/09/06 Javascript
vue 实现购物车总价计算
2019/11/06 Javascript
vue实现一个获取按键展示快捷键效果的Input组件
2021/01/13 Vue.js
python中实现php的var_dump函数功能
2015/01/21 Python
Python实现将xml导入至excel
2015/11/20 Python
Python 比较两个数组的元素的异同方法
2017/08/17 Python
Python设计模式之代理模式实例详解
2019/01/19 Python
Python数据类型之Dict字典实例详解
2019/05/07 Python
pytorch实现CNN卷积神经网络
2020/02/19 Python
html5 冒号分隔符对齐的实现
2019/07/31 HTML / CSS
美国轮胎网站:Priority Tire
2018/11/28 全球购物
linux面试题参考答案(10)
2016/10/26 面试题
教师师德反思材料
2014/02/15 职场文书
学校课外活动总结
2014/05/08 职场文书
优秀学生干部个人事迹材料
2014/06/02 职场文书
化学专业大学生职业生涯规划范文
2014/09/13 职场文书
JavaScript原型链中函数和对象的理解
2022/06/16 Javascript