# python将多个excel合并
Date: 2021-02-03


同一个excel文件，分配到各组填写， 最后统一汇总成一个文档反馈。

#### 环境

- - windows10
    - python3.7 + openpyxl

#### 目标

- - in目录存放各个组填写的文档
    - out目录存放合并后的结果文件

#### 实现

- 表格

| 序号 | 产品 | 信息 | 反馈1 | 反馈2 |
| --- | --- | --- | --- | --- |
| 01 | 产品1 | X | 00000 | 999999 |
| 02 | 产品2 | X | 11111 | 888888 |
| 03 | 产品3 | X | 22222 | 777777 |

- 代码:

```
from openpyxl import load_workbook
from openpyxl import Workbook
import os

##  获取所有的文件
def getfilelist(dirname):
    li = []
    for f in os.listdir(dirname):
        if f.endswith('.xlsx'):
            li.append(f)
    return li

##  更新
##  1. 打开输出文件，处理一个sheet页面， 
##  2. 循环获取某一行记录，放入字典结构从所有的输入文件中获取补充记录
##  3. 如果是单条直接更新， 如果出现重复记录入职(暂不处理)
##  4. 依据以上处理方式，处理完所有sheet页面

INPATH=".\\in\\" 
OUTPATH=".\\out\\" 
productlist = ('product1','product2')
## 1. sheetname名称
## 2. 位置1: 过滤条件 product 所在列位置，判断是否productlist
## 3. 位置2：通过判断第一个需要填写项判断是否填写数据
sheetlist = ( ('sheet1）', 6, 15), 
        ('sheet2', 6, 13),
        ('sheet3', 5, 12), 
        ('sheet4', 6, 14))

def update(): 
    inlist  = getfilelist(".\\in")
    outlist = getfilelist(".\\out")
    for li in sheetlist:
        sheetname = li[0]
        product = li[1]
        firstfilled= li[2]
        d = readdata(inlist, sheetname, product, firstfilled)
        writedata(outlist, d, sheetname)

def readdata(inlist, sheetname, product, firstfilled): 
    d = {}
    for i in inlist:
        wb = load_workbook(filename = INPATH+i)
        ws = wb[sheetname]
        row = tuple(ws.rows)
        c = filter(lambda cell: (cell[product].value in productlist) and (cell[firstfilled].value is not None), row)
        for cell in c:
            d[cell[0].row] = cell 
    return d

def writedata(outlist, d, sheetname):
    wbout = load_workbook(filename = OUTPATH+outlist[0])
    wsout = wbout[sheetname]
    print(sheetname)

    #for key in d.keys():    for key in d:
        for col in range(1, wsout.max_column+1):
            wsout.cell(row=key, column=col).value = d[key][col-1].value

    wbout.save(filename = OUTPATH+outlist[0])

update()

```

代码调整:

```
for key in d.keys():
-->
for key in d:
```

字典keys()方法遍历前会生成临时列表， 导致消耗大量内存， 应使用默认iterator方式。

#### 参考

[Openpyxl Doc](https://openpyxl.readthedocs.io/en/stable/index.html#)

极客时间-python核心技术与实战

Photo by  Jη ✿@Jeanne\_8L from twitter

