cqwcns 发表于 2020-12-16 11:21

python+openpyxl读取excel写入到另一个excel

我在尝试用python做一个Excel通报数据加工自动化,数据加工部分已基本完成,功能实现。
具体是导入各类源数据,进行合并,再用pandas加工数据,在分sheet保存到Excel。


现在问题卡在最后一步,事情是这样的,python的只要目的是加工数据,通报模板还是通过Excel公式来实现,这样用户修改更灵活。
我希望将'通报模板.xlsx'的sheet直接写入输出的通报文件,但这样写报错,不知道要怎么写,请指教,谢谢。

问题位置代码:
# ..........忽略以上代码,完整代码可见下文...............
# =====通报模板=====
print("[操作] 输入通报模板")
xlsxNotification = load_workbook(filename=pathSourceData + "\\" + '通报模板.xlsx')
sheetNotification = xlsxNotification['sheet']

# 输出Excel文件,判断表是否存在,如果存在则写入Excel。
print("[操作] 输出EXCEL表")
with pd.ExcelWriter('日通报源数据' + datetime.datetime.now().strftime('%Y年%m月%d日%H时') + '.xlsx') as writer:
# 写入通报sheet
sheetNotification.to_excel(writer, sheet_name='通报', index=False)
#再写入源数据数据    if "sheetNewDistribution" in locals().keys():
      sheetNewDistribution.to_excel(writer, sheet_name='新派', index=False)
    if "sheetOnTheWay" in locals().keys():
      sheetOnTheWay.to_excel(writer, sheet_name='在途', index=False)
    if "sheetClosedLoop" in locals().keys():
      sheetClosedLoop.to_excel(writer, sheet_name='归档', index=False)
    if "dataFrameAttendance" in locals().keys():
      dataFrameAttendance.to_excel(writer, sheet_name='休假', index=False, columns=['区域', '所属装维组', '装维姓名', '装维账号',
                                                                                    datetime.datetime.now().strftime(
                                                                                        '%Y-%m-%d')])


报错内容:
Traceback (most recent call last):
File "D:/python/pyJieDuanTongBao/pyJieDuanTongBao.py", line 378, in <module>
    sheetNotification.to_excel(writer, sheet_name='通报', index=False)
AttributeError: 'Worksheet' object has no attribute 'to_excel'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "D:/python/pyJieDuanTongBao/pyJieDuanTongBao.py", line 387, in <module>
    dataFrameAttendance.to_excel(writer, sheet_name='休假', index=False, columns=['区域', '所属装维组', '装维姓名', '装维账号',
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\pandas\io\excel\_base.py", line 777, in __exit__
    self.close()
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\pandas\io\excel\_base.py", line 781, in close
    return self.save()
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\pandas\io\excel\_openpyxl.py", line 43, in save
    return self.book.save(self.path)
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\openpyxl\workbook\workbook.py", line 392, in save
    save_workbook(self, filename)
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\openpyxl\writer\excel.py", line 293, in save_workbook
    writer.save()
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\openpyxl\writer\excel.py", line 275, in save
    self.write_data()
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\openpyxl\writer\excel.py", line 89, in write_data
    archive.writestr(ARC_WORKBOOK, writer.write())
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\openpyxl\workbook\_writer.py", line 148, in write
    self.write_views()
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\openpyxl\workbook\_writer.py", line 135, in write_views
    active = get_active_sheet(self.wb)
File "D:\Program Files\anaconda\envs\playData\lib\site-packages\openpyxl\workbook\_writer.py", line 33, in get_active_sheet
    raise IndexError("At least one sheet must be visible")
IndexError: At least one sheet must be visible


完整代码:
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os
import datetime
import numpy as np
import pandas as pd
from openpyxl import Workbook
from openpyxl import load_workbook
from collections import Counter

# 获取当前时间
timeNow = datetime.datetime.now()
# 获取今天零点
timeZeroToday = timeNow - datetime.timedelta(hours=timeNow.hour, minutes=timeNow.minute, seconds=timeNow.second,
                                             microseconds=timeNow.microsecond)
# 获取今天23:59:59
timeLastToday = timeZeroToday + datetime.timedelta(hours=23, minutes=59, seconds=59)

# 声明源数据路径
pathSourceData = "源数据"
# 声明新派、在途和归档3个文件列表
listFilesNewDistribution = []
listFilesOnTheWay = []
listFilesClosedLoop = []
listOverNightOnTheWay = []
fileAttendance = ""

# 获得源数据文件夹的全部文件名称,并对CSV文件进行分类
dirSourceData = os.listdir(pathSourceData)
for file in dirSourceData:
    if os.path.splitext(file) == ".csv":
      if "新派" in file:
            listFilesNewDistribution.append(file)
      elif "在途" in file:
            listFilesOnTheWay.append(file)
      elif "归档" in file:
            listFilesClosedLoop.append(file)
      elif "家客工单导出" in file:
            listOverNightOnTheWay.append(file)
    elif os.path.splitext(file) == ".xlsx":
      if "排班" in file:
            fileAttendance = file

# 区域网格字典
dictRegionsGrids = {'茂南': ['开发区', '茂北', '西城', '油城北', '油城东', '油城南'],
                  '电白': ['滨海', '林头', '麻岗', '南海', '沙琅', '水东'],
                  '高州': ['大井', '高城北', '高城南', '根子', '石鼓', '长坡'],
                  '化州': ['合江', '河东', '化北', '化河西', '同庆', '杨梅'],
                  '信宜': ['北界', '城北', '城南', '合水', '钱排', '朱砂']}


# 获得区域函数
def getRegion(x):
    for iRegion in dictRegionsGrids:
      if str(x.装维组用户班).find(iRegion) >= 0:
            return iRegion
    for iRegion in dictRegionsGrids:
      if str(x.标准地址).find(iRegion) >= 0:
            return iRegion
    for iRegion in dictRegionsGrids:
      if str(x.五级地址名称).find(iRegion) >= 0:
            return iRegion
    for iRegion in dictRegionsGrids:
      if str(x.二级地址名称).find(iRegion) >= 0:
            return iRegion

    return "未签收"


# 获得区域函数(仅装维组)
def getRegionOnGroup(x):
    for iRegion in dictRegionsGrids:
      if str(x.所属装维组).find(iRegion) >= 0:
            return iRegion
    return "未知"


# 获得网格函数
def getGrid(x):
    for iRegion in dictRegionsGrids:
      if iRegion == str(x.区域):
            for iGrid in dictRegionsGrids:
                if str(x.装维组用户班).find(iGrid) >= 0:
                  return iGrid

    return "未签收"


# 获得产品名称函数
listOriginalProductName = ['宽带', '手机宽带基础产品', '手机宽带', '宽带电视基础产品', '智能组网及增值收费服务基础产品', '智慧管家基础安装服务']
listFinalProductName = ['宽带', '宽带', '宽带', '电视', '组网', '安防']


def getProductName(x):
    if x.操作类型 == '业务移机' or ():
      return '移机'
    else:
      for iProductName in range(len(listOriginalProductName)):
            if listOriginalProductName == x.产品名称:
                if listFinalProductName == '宽带' and x.操作类型 == '预勘查' and x.产品业务属性 == '存量业务':
                  return '移机'
                else:
                  return listFinalProductName
    return "未知"


# =====隔夜在途工单=====
if len(listOverNightOnTheWay) < 1:
    print("[错误] 未找到隔夜在途源数据(家客工单导出)")
else:
    print("[操作] 输入隔夜在途数据")
    count = 0
    for i in listOverNightOnTheWay:
      if count == 0:
            sheetOverNightOnTheWay = pd.read_csv(pathSourceData + "\\" + i, encoding='gbk', usecols=['工单号', '标准地址'])
            count += 1
      else:
            sheetTemp = pd.read_csv(pathSourceData + "\\" + i, encoding='gbk', usecols=['工单号', '标准地址'])
            sheetOverNightOnTheWay = pd.concat()

    # 重置索引(index)
    sheetOverNightOnTheWay = sheetOverNightOnTheWay.reset_index(drop=True)

# =====人员出勤情况=====
print('[操作] 输入人员出勤数据')
# 输入Excel文件
xlsxAttendance = load_workbook(pathSourceData + "\\" + fileAttendance, read_only=False)
sheetAttendance = xlsxAttendance.active
# 转换为DataFrame
dataFrameAttendance = pd.DataFrame(sheetAttendance.values)
# 设置字段名
dataFrameAttendance.columns = dataFrameAttendance.iloc
dataFrameAttendance = dataFrameAttendance.drop(0)
# 新增[区域]列,并根据getRegionOnGroup函数规则获得区域
dataFrameAttendance['区域'] = dataFrameAttendance.apply(lambda x: getRegionOnGroup(x), axis=1)
# 清洗上班人员
dataFrameAttendance = dataFrameAttendance.drop(
    dataFrameAttendance == '上班'].index)
# =====新派=====
# 如果有新派数据,就先输入第一个,再循环输入剩余的并合并
if len(listFilesNewDistribution) < 1:
    print("[错误] 未找到新派源数据")
else:
    print("[操作] 输入新派数据")
    count = 0
    for i in listFilesNewDistribution:
      if count == 0:
            sheetNewDistribution = pd.read_csv(pathSourceData + "\\" + i, encoding='gbk')
            count += 1
      else:
            sheetTemp = pd.read_csv(pathSourceData + "\\" + i, encoding='gbk')
            sheetNewDistribution = pd.concat()

    print("[操作] 处理新派数据")
    # 重置索引(index)
    sheetNewDistribution = sheetNewDistribution.reset_index(drop=True)

    # 格式化日期
    sheetNewDistribution['派单日期'] = pd.to_datetime(sheetNewDistribution['派单日期'])
    sheetNewDistribution['勘察单到单时间'] = pd.to_datetime(sheetNewDistribution['勘察单到单时间'])
    # 账号转换为字符串
    sheetNewDistribution['宽带帐号'] = sheetNewDistribution['宽带帐号'].apply(str)

    # 清洗不需要的行
    # 产品名称=家客试开通
    sheetNewDistribution = sheetNewDistribution.drop(
      sheetNewDistribution == '家客试开通'].index)
    # 备注包含测试且派单日期在2020年前
    sheetNewDistribution = sheetNewDistribution.drop(
      sheetNewDistribution[
            (sheetNewDistribution['勘察单到单时间'].notnull()) & (sheetNewDistribution['操作类型'] == '业务开通')].index)
    # 备注包含测试且派单日期在2020年前
    sheetNewDistribution = sheetNewDistribution.drop(
      sheetNewDistribution[
            (sheetNewDistribution['备注'].str.contains('测试')) & (sheetNewDistribution['派单日期'].dt.year < 2020)].index)
    # 资源类型等于自建宽带、自建铁通融合宽带,或包含三个指定地址的,保留,其他清洗
    sheetNewDistribution['是否纳入统计'] = sheetNewDistribution.apply(
      lambda x: "是" if x.资源类型 == '自建宽带' or x.资源类型 == '自建铁通融合宽带' or str(x.五级地址名称).find('海心路茂名职业技术学院') >= 0 or str(
            x.五级地址名称).find('海城路五路1号茂名职业技术学院') >= 0 or str(x.五级地址名称).find('官渡街道文明路茂名职业技术') >= 0 else "否", axis=1)
    # 开始清洗资源类型
    sheetNewDistribution = sheetNewDistribution.drop(sheetNewDistribution == '否'].index)
    sheetNewDistribution = sheetNewDistribution.drop(['是否纳入统计'], axis=1)

    # 修改不合法的字段名
    sheetNewDistribution = sheetNewDistribution.rename(columns={'装维组/用户班': '装维组用户班'})
    sheetNewDistribution = sheetNewDistribution.rename(columns={'装维人员/用户班人员': '装维人员用户班人员'})

    # 新增标准地址列,并匹配标准地址
    sheetNewDistribution = pd.merge(sheetNewDistribution, sheetOverNightOnTheWay, on=['工单号', '工单号'], how='left')

    # 新增[区域]列,并根据getRegion函数规则获得区域
    sheetNewDistribution['区域'] = sheetNewDistribution.apply(lambda x: getRegion(x), axis=1)
    # 新增[网格]列,并根据getGrid函数规则获得网格
    sheetNewDistribution['网格'] = sheetNewDistribution.apply(lambda x: getGrid(x), axis=1)
    # 新增[装维人员]列,获得装维人员
    sheetNewDistribution['装维人员'] = sheetNewDistribution['装维人员用户班人员'].apply(lambda x: '未签收' if pd.isnull(x) else x)
    # 新增[产品名称分类]列,并根据getProductName函数规则获得产品名称分类
    sheetNewDistribution['产品名称分类'] = sheetNewDistribution.apply(lambda x: getProductName(x), axis=1)
    # 新增[是否集约环节]列,获得判断工单是否在集约环节
    sheetNewDistribution['是否集约环节'] = sheetNewDistribution['当前环节'].apply(lambda x: "集约环节" if x == "集中预约" else "非集约环节")
    # 新增[实际到单时间]列,获得实际到单时间
    sheetNewDistribution['实际到单时间'] = sheetNewDistribution.apply(lambda x: x.派单日期 if pd.isnull(x.勘察单到单时间) else x.勘察单到单时间,
                                                                axis=1)

    # 宽带存量剔除
    sheetNewDistribution = sheetNewDistribution.drop(
      sheetNewDistribution[
            (sheetNewDistribution['产品名称分类'] == '宽带') & (sheetNewDistribution['产品业务属性'] == '存量业务')].index)

    # 重置索引(index)
    sheetNewDistribution = sheetNewDistribution.reset_index(drop=True)

# =====在途=====
# 如果有在途数据,就先输入第一个,再循环输入剩余的并合并
if len(listFilesOnTheWay) < 1:
    print("[错误] 未找到在途源数据")
else:
    print("[操作] 输入在途数据")
    count = 0
    for i in listFilesOnTheWay:
      if count == 0:
            sheetOnTheWay = pd.read_csv(pathSourceData + "\\" + i, encoding='gbk')
            count += 1
      else:
            sheetTemp = pd.read_csv(pathSourceData + "\\" + i, encoding='gbk')
            sheetOnTheWay = pd.concat()

    print("[操作] 处理在途数据")
    # 重置索引(index)
    sheetOnTheWay = sheetOnTheWay.reset_index(drop=True)

    # 格式化日期
    sheetOnTheWay['派单日期'] = pd.to_datetime(sheetOnTheWay['派单日期'])
    sheetOnTheWay['勘察单到单时间'] = pd.to_datetime(sheetOnTheWay['勘察单到单时间'])
    # 账号转换为字符串
    sheetOnTheWay['宽带帐号'] = sheetOnTheWay['宽带帐号'].apply(str)

    # 清洗不需要的行
    # 产品名称=家客试开通
    sheetOnTheWay = sheetOnTheWay.drop(sheetOnTheWay == '家客试开通'].index)
    # 备注包含测试且派单日期在2020年前
    sheetOnTheWay = sheetOnTheWay.drop(
      sheetOnTheWay[(sheetOnTheWay['备注'].str.contains('测试')) & (sheetOnTheWay['派单日期'].dt.year < 2020)].index)
    # 资源类型等于自建宽带、自建铁通融合宽带、产品名称为组网,或包含三个指定地址的,保留,其他清洗
    sheetOnTheWay['是否纳入统计'] = sheetOnTheWay.apply(
      lambda x: "是" if x.资源类型 == '自建宽带' or x.资源类型 == '自建铁通融合宽带' or str(x.五级地址名称).find('海心路茂名职业技术学院') >= 0 or str(
            x.五级地址名称).find('海城路五路1号茂名职业技术学院') >= 0 or str(x.五级地址名称).find(
            '官渡街道文明路茂名职业技术') >= 0 or x.产品名称 == '智能组网及增值收费服务基础产品' else "否", axis=1)
    # 开始清洗资源类型
    sheetOnTheWay = sheetOnTheWay.drop(sheetOnTheWay == '否'].index)
    sheetOnTheWay = sheetOnTheWay.drop(['是否纳入统计'], axis=1)

    # 修改不合法的字段名
    sheetOnTheWay = sheetOnTheWay.rename(columns={'装维组/用户班': '装维组用户班'})
    sheetOnTheWay = sheetOnTheWay.rename(columns={'装维人员/用户班人员': '装维人员用户班人员'})

    # 新增标准地址列,并匹配标准地址
    sheetOnTheWay = pd.merge(sheetOnTheWay, sheetOverNightOnTheWay, on=['工单号', '工单号'], how='left')

    # 新增[区域]列,并根据getRegion函数规则获得区域
    sheetOnTheWay['区域'] = sheetOnTheWay.apply(lambda x: getRegion(x), axis=1)
    # 新增[网格]列,并根据getGrid函数规则获得网格
    sheetOnTheWay['网格'] = sheetOnTheWay.apply(lambda x: getGrid(x), axis=1)
    # 新增[装维人员]列,获得装维人员
    sheetOnTheWay['装维人员'] = sheetOnTheWay['装维人员用户班人员'].apply(lambda x: '未签收' if pd.isnull(x) else x)
    # 新增[产品名称分类]列,并根据getProductName函数规则获得产品名称分类
    sheetOnTheWay['产品名称分类'] = sheetOnTheWay.apply(lambda x: getProductName(x), axis=1)
    # 新增[是否集约环节]列,获得判断工单是否在集约环节
    sheetOnTheWay['是否集约环节'] = sheetOnTheWay['当前环节'].apply(lambda x: "集约环节" if x == "集中预约" else "非集约环节")
    # 新增[实际到单时间]列,获得实际到单时间
    sheetOnTheWay['实际到单时间'] = sheetOnTheWay.apply(lambda x: x.派单日期 if pd.isnull(x.勘察单到单时间) else x.勘察单到单时间, axis=1)
    # 新增[自然时间]列,获得当前自然时间
    sheetOnTheWay['自然时间'] = timeNow
    # 新增[跨日时间]列,获得当前跨日时间
    sheetOnTheWay['跨日时间'] = timeLastToday
    # 新增[工单自然时长]列,计算工单自然时长
    sheetOnTheWay['工单自然时长'] = sheetOnTheWay['实际到单时间'].apply(lambda x: int((timeNow - x).total_seconds()) / 3600)
    # 新增[工单跨日时长]列,计算工单跨日时长
    sheetOnTheWay['工单跨日时长'] = sheetOnTheWay['实际到单时间'].apply(lambda x: int((timeLastToday - x).total_seconds()) / 3600)
    # 新增[是否超7天]列,计算是否超7天(大于168小时)
    sheetOnTheWay['是否超7天'] = sheetOnTheWay['工单跨日时长'].apply(lambda x: "是" if x > 168 else "否")

    # 存量剔除
    sheetOnTheWay = sheetOnTheWay.drop(
      sheetOnTheWay[((sheetOnTheWay['产品名称分类'] == '宽带') | (sheetOnTheWay['产品名称分类'] == '电视')) & (
                sheetOnTheWay['产品业务属性'] == '存量业务')].index)

    # 新增[是否同装]列,根据账号是否重复,判断是否为同装业务
    sheetTemp = sheetOnTheWay
    listTemp = sheetTemp['宽带帐号'].tolist()
    sheetOnTheWay['是否与宽带同装'] = sheetOnTheWay.apply(lambda x: '是' if x.宽带帐号 in listTemp and x.产品名称分类 != '宽带' else '否',
                                                   axis=1)

    # 重置索引(index)
    sheetOnTheWay = sheetOnTheWay.reset_index(drop=True)

# =====归档=====
# 如果有归档数据,就先输入第一个,再循环输入剩余的并合并
if len(listFilesClosedLoop) < 1:
    print("[错误] 未找到归档源数据")
else:
    print("[操作] 输入归档数据")
    count = 0
    for i in listFilesClosedLoop:
      if count == 0:
            sheetClosedLoop = pd.read_csv(pathSourceData + "\\" + i, encoding='gbk')
            count += 1
      else:
            sheetTemp = pd.read_csv(pathSourceData + "\\" + i, encoding='gbk')
            sheetClosedLoop = pd.concat()

    print("[操作] 处理归档数据")
    # 重置索引(index)
    sheetClosedLoop = sheetClosedLoop.reset_index(drop=True)

    # 格式化日期
    sheetClosedLoop['派单日期'] = pd.to_datetime(sheetClosedLoop['派单日期'])
    sheetClosedLoop['勘察单到单时间'] = pd.to_datetime(sheetClosedLoop['勘察单到单时间'])
    sheetClosedLoop['归档时间'] = pd.to_datetime(sheetClosedLoop['归档时间'])

    # 清洗不需要的行
    # 产品名称=家客试开通
    sheetClosedLoop = sheetClosedLoop.drop(sheetClosedLoop == '家客试开通'].index)
    # 备注包含测试且派单日期在2020年前
    sheetClosedLoop = sheetClosedLoop.drop(
      sheetClosedLoop[(sheetClosedLoop['备注'].str.contains('测试')) & (sheetClosedLoop['派单日期'].dt.year < 2020)].index)
    # 资源类型等于自建宽带、自建铁通融合宽带、产品名称为组网,或包含三个指定地址的,保留,其他清洗
    sheetClosedLoop['是否纳入统计'] = sheetClosedLoop.apply(
      lambda x: "是" if x.资源类型 == '自建宽带' or x.资源类型 == '自建铁通融合宽带' or str(x.五级地址名称).find('海心路茂名职业技术学院') >= 0 or str(
            x.五级地址名称).find('海城路五路1号茂名职业技术学院') >= 0 or str(x.五级地址名称).find(
            '官渡街道文明路茂名职业技术') >= 0 or x.产品名称 == '智能组网及增值收费服务基础产品' else "否", axis=1)
    # 开始清洗资源类型
    sheetClosedLoop = sheetClosedLoop.drop(sheetClosedLoop == '否'].index)
    sheetClosedLoop = sheetClosedLoop.drop(['是否纳入统计'], axis=1)

    # 修改不合法的字段名
    sheetClosedLoop = sheetClosedLoop.rename(columns={'装维组/用户班': '装维组用户班'})
    sheetClosedLoop = sheetClosedLoop.rename(columns={'装维人员/用户班人员': '装维人员用户班人员'})

    # 新增标准地址列,并匹配标准地址
    sheetClosedLoop = pd.merge(sheetClosedLoop, sheetOverNightOnTheWay, on=['工单号', '工单号'], how='left')

    # 新增[区域]列,并根据getRegion函数规则获得区域
    sheetClosedLoop['区域'] = sheetClosedLoop.apply(lambda x: getRegion(x), axis=1)
    # 新增[网格]列,并根据getGrid函数规则获得网格
    sheetClosedLoop['网格'] = sheetClosedLoop.apply(lambda x: getGrid(x), axis=1)
    # 新增[装维人员]列,获得装维人员
    sheetClosedLoop['装维人员'] = sheetClosedLoop['装维人员用户班人员'].apply(lambda x: '未签收' if pd.isnull(x) else x)
    # 新增[产品名称分类]列,并根据getProductName函数规则获得产品名称分类
    sheetClosedLoop['产品名称分类'] = sheetClosedLoop.apply(lambda x: getProductName(x), axis=1)
    # 新增[归档时段]列,根据归档时间获得工单归档时段
    sheetClosedLoop['归档时段'] = sheetClosedLoop['归档时间'].apply(lambda x: x.hour)

    # 宽带存量剔除
    sheetClosedLoop = sheetClosedLoop.drop(
      sheetClosedLoop[(sheetClosedLoop['产品名称分类'] == '宽带') & (sheetClosedLoop['产品业务属性'] == '存量业务')].index)

    # 新增[是否同装]列,根据账号是否重复,判断是否为同装业务
    sheetTemp = sheetClosedLoop
    listTemp = sheetTemp['宽带帐号'].tolist()
    sheetClosedLoop['是否与宽带同装'] = sheetClosedLoop.apply(
      lambda x: '是' if x.宽带帐号 in listTemp and x.产品名称分类 != '宽带' else '否',
      axis=1)

    # 重置索引(index)
    sheetClosedLoop = sheetClosedLoop.reset_index(drop=True)

# =====通报模板=====
print("[操作] 输入通报模板")
xlsxNotification = load_workbook(filename=pathSourceData + "\\" + '通报模板.xlsx')
sheetNotification = xlsxNotification['sheet']

# 输出Excel文件,判断表是否存在,如果存在则写入Excel。
print("[操作] 输出EXCEL表")
with pd.ExcelWriter('日通报源数据' + datetime.datetime.now().strftime('%Y年%m月%d日%H时') + '.xlsx') as writer:
# 写入通报sheet
    sheetNotification.to_excel(writer, sheet_name='通报', index=False)
#再写入源数据数据
    if "sheetNewDistribution" in locals().keys():
      sheetNewDistribution.to_excel(writer, sheet_name='新派', index=False)
    if "sheetOnTheWay" in locals().keys():
      sheetOnTheWay.to_excel(writer, sheet_name='在途', index=False)
    if "sheetClosedLoop" in locals().keys():
      sheetClosedLoop.to_excel(writer, sheet_name='归档', index=False)
    if "dataFrameAttendance" in locals().keys():
      dataFrameAttendance.to_excel(writer, sheet_name='休假', index=False, columns=['区域', '所属装维组', '装维姓名', '装维账号',
                                                                                    datetime.datetime.now().strftime(
                                                                                        '%Y-%m-%d')])

iprogramer 发表于 2020-12-16 12:13

本帖最后由 iprogramer 于 2020-12-16 12:28 编辑

错误指出是 sheetNotification对象没有to_excel方法,个人不是很懂,可以看看openpyexcel的文档

根据你的程序,sheetNotification应该是个sheet对象,to_excel是pd里面的方法,必须将sheetNotification转化成DataFrame对象,才能调用to_excel

xlsxNotification = load_workbook(filename=pathSourceData + "\\" + '通报模板.xlsx')
sheetNotification = xlsxNotification['sheet']


换成
sheetNotification = pd.read_excel(filename=pathSourceData + "\\" + '通报模板.xlsx',sheet_name='sheet')


试试



sondaa 发表于 2020-12-16 12:26

我也正在做,一个类似的。但是不是很明白,不是计算机专业的。初学。

bitter清酒 发表于 2020-12-16 13:57

感谢楼主,楼主牛逼

mlhqhj 发表于 2020-12-16 14:08

本帖最后由 mlhqhj 于 2020-12-16 14:10 编辑

观摩学习一下,近期正在做有关通讯费用表格,和这个类似

zhaoyf18 发表于 2020-12-16 14:21

观摩学习一下,近期正在做有关通讯费用表格,和这个类似

cqwcns 发表于 2020-12-16 14:32

iprogramer 发表于 2020-12-16 12:13
错误指出是 sheetNotification对象没有to_excel方法,个人不是很懂,可以看看openpyexcel的文档

根据你 ...


TypeError: read_excel() got an unexpected keyword argument 'filename'

{:301_972:}

cqwcns 发表于 2020-12-16 16:09

换了一个思路,直接在现有文件(通报.xlsx)上追加写入。

# 输出Excel文件,判断表是否存在,如果存在则写入Excel。
print("[操作] 输出EXCEL表")
strResultPath = pathSourceData + "\\" + '通报模板.xlsx'
bookResult = load_workbook(strResultPath)
writer = pd.ExcelWriter(strResultPath, engine='openpyxl')
writer.book = bookResult
if "sheetNewDistribution" in locals().keys():
    sheetNewDistribution.to_excel(writer, '新派', index=False)
if "sheetOnTheWay" in locals().keys():
    sheetOnTheWay.to_excel(writer, '在途', index=False)
if "sheetClosedLoop" in locals().keys():
    sheetClosedLoop.to_excel(writer, '归档', index=False)
if "dataFrameAttendance" in locals().keys():
    dataFrameAttendance.to_excel(writer, '休假', index=False,
                                 columns=['区域', '所属装维组', '装维姓名', '装维账号', datetime.datetime.now().strftime('%Y-%m-%d')])
writer.save()
writer.close()

iprogramer 发表于 2020-12-16 17:26

cqwcns 发表于 2020-12-16 14:32
TypeError: read_excel() got an unexpected keyword argument 'filename'

把filename去掉,直接写路径就行

antcna 发表于 2020-12-20 18:26

楼主,你这个通报的表头是多级的吗?pandas中如何读取原表的多级表头,然后保存新表时也显示同样的多级表头?
页: [1]
查看完整版本: python+openpyxl读取excel写入到另一个excel