m_obj = re.match("(?:(\d+)年)?(\d+)月", sht.Name)
if not m_obj:
continue
i += 1
year, month = m_obj.groups()
year = 2021 if year == "" else 2022
date = f"'{year}年{month:0>2}月"
sht.Activate()
max_rows = sht.Range("B7").End(constants.xlDown).Row
max_cols = sht.Range("B7").End(constants.xlToRight).Column
n = 7 if i == 1 else 8
rng = sht.Range(sht.Cells(n, 1), sht.Cells(max_rows, max_cols))
rng.Select()
excel_app.Selection.Copy()
dest.Activate()
dest.Range(f"A{pos}").Activate()
dest.Paste()
if i == 1:
# 复制第一张工作表的列宽
dest.PasteSpecial(constants.xlPasteColumnWidths)
dates.extend([date]\*(max_rows-7))
print(sht.Name, date, max_rows, max_cols)
pos += max_rows-n+1
excel_app.ScreenUpdating = True dest.Columns("B:B").Insert() dest.Range("B1").Value2 = "月份" dest.Range("B2").GetResize(len(dates)).Value = excel_app.WorksheetFunction.Transpose(dates) dest.Columns("B:B").ColumnWidth = 20 dest.Columns("B:B").AutoFit() dest.Range("A2").Value2 = "1" dest.Range("A2").Select() excel_app.Selection.AutoFill(dest.Range( f"A2:A{pos-1}"), constants.xlFillDefault) dest.Columns("A:A").AutoFit() dest.Rows(f"1:{pos-1}").AutoFit() dest.Name = "总表"
保存并退出
filename = re.sub(".[^.]+$", "", filename) wb_result.SaveAs(os.path.abspath(f"{filename}_合并.xlsx")) wb_result.Close()
最终合并结果如下:

## 带格式合并表格的JS宏实现
关于js宏的基础知识,之前已经分享过很多了,有兴趣可以查看前文:
>
> WPS JS宏入门案例集锦
> <https://xxmdmst.blog.csdn.net/article/details/127097880>
>
>
> WPS JS宏示例-批量添加链接
> <https://xxmdmst.blog.csdn.net/article/details/127037824>
>
>
> JS宏综合示例-多维度筛选统计 带窗体
> <https://xxmdmst.blog.csdn.net/article/details/127138015>
>
>
>
本需求最终对应宏代码如下:
function 合并并插入()
{
console.clear();
Application.ScreenUpdating = false;
var wb=ActiveWorkbook;
var wb_result = Workbooks.Add();
var dest = wb_result.Sheets(1);
var i=0, pos=1;
dates=[];
for(var sht of wb.Sheets){
let arr=/(?:(\d+)年)?(\d+)月/.exec(sht.Name);
if(arr==undefined) continue;
i += 1;
var [_,year,month]=arr;
year = year==undefined?2021:2022;
if(month.length==1) month="0"+month;
date = '${year}年${month}月;
console.log(date);
sht.Activate();
let max_rows = sht.Range("B7").End(xlDown).Row;
let max_cols = sht.Range("B7").End(xlToRight).Column;
n = i==1?7:8;
rng = sht.Range(sht.Cells(n, 1), sht.Cells(max_rows, max_cols));
rng.Select();
Selection.Copy();
dest.Activate();
dest.Range(A${pos}).Activate();
dest.Paste();
// 复制第一张工作表的列宽
if(i==1) dest.PasteSpecial(xlPasteColumnWidths);
for(k=0;k<max_rows-7;k++) dates.push(date);
pos += max_rows-n+1;
}
Application.ScreenUpdating = true;
dest.Columns("B:B").Insert();
dest.Range("B1").Value2 = "月份";
dest.Range("B2").Resize(dates.length).Value2 = WorksheetFunction.Transpose(dates);
dest.Columns.Item("B:B").ColumnWidth = 20;
dest.Columns.Item("B:B").AutoFit();
dest.Range("A2").Value2 = "1";
dest.Range("A2").Select();
Selection.AutoFill(dest.Range(A2:A${pos-1}), xlFillDefault);
dest.Columns("A:A").AutoFit();
dest.Rows(1:${pos-1}).AutoFit();
dest.Name = "总表";
wb_result.SaveAs(${wb.Path}\\${wb.Name.replace(/\.[^.]+$/,"")}\_合并.xlsx);
}
结果得到与上述完全一致的结果。
>
> 注意:COM组件提供Python的接口Resize方法失效,可以使用GetResize替代。
>
>
>
## 保留样式拆分表格的Python实现
之前的完整实现方法请查看:
>
> 深度剖析Excel表拆分的三项技术
> https://xxmdmst.blog.csdn.net/article/details/118655016
>
>
>
今天的实现只考虑将当前工作表拆分到工作簿中的情况,相对之前的代码会有一定简化,同时增加了复制列宽的功能,重新填充编号的功能。完整代码如下:
import win32com.client as win32 # 导入模块 from win32com.client import constants import os
def simple_split_excel(filename, group_num, title_row=1, excel_app=win32.gencache.EnsureDispatch('Excel.Application')): """作者小小明的csdn:blog.csdn.net/as604049322""" filename = os.path.abspath(filename) wb = excel_app.Workbooks.Open(filename) try: sheet = wb.ActiveSheet max_rows = sheet.UsedRange.Rows.Count max_cols = sheet.UsedRange.Columns.Count # 获取总表的数据区域 rng = sheet.Range(sheet.Cells(title_row, 1), sheet.Cells(max_rows, max_cols)) if title_row > 1: # 获取标题行前面的区域 start = sheet.Range(sheet.Cells( 1, 1), sheet.Cells(title_row-1, max_cols)) # 读取表头名称列表 header = sheet.Range(sheet.Cells(title_row, 1), sheet.Cells(title_row, max_cols)).Value[0] # 如果传入列名则找出列所在的位置 if isinstance(group_num, str): for i, value in enumerate(header, 1): if group_num == value: group_num = i break names = sum(sheet.Range(sheet.Cells(title_row+1, group_num), sheet.Cells(max_rows, group_num)).Value, tuple()) names = set(filter(None, names)) excel_app.ScreenUpdating = False for name in names: new_sheet = wb.Sheets.Add(After=wb.Sheets(wb.Sheets.Count)) new_sheet.Name = name if title_row > 1: # 先复制标题行之前的区域 wb.Activate() sheet.Activate() start.Copy() new_sheet.Activate() new_sheet.Range("A1").Activate() new_sheet.Paste() sheet.Activate() rng.AutoFilter(Field=group_num, Criteria1=name) rng.Copy() new_sheet.Activate() new_sheet.Range(f"A{title_row}").Activate() new_sheet.Paste() new_sheet.PasteSpecial(constants.xlPasteColumnWidths)
new_sheet.Range("A2").Value2 = "1"
new_sheet.Range("A2").Select()
max_rows = new_sheet.Range("A1").End(constants.xlDown).Row
excel_app.Selection.AutoFill(new_sheet.Range(
f"A2:A{max\_rows}"), constants.xlFillDefault)
excel_app.ScreenUpdating = True
sheet.AutoFilterMode = False
wb.Save()
finally:
wb.Close()
调用该代码:
simple_split_excel("异常项清理明细_合并.xlsx", "业务系统归属业务员")
拆分结果如下:

## 保留样式拆分表格的JS宏实现
完整代码如下:
function excel表拆分() { console.clear(); let group_num="业务系统归属业务员", title_row=1; var wb=ActiveWorkbook; var sht = wb.ActiveSheet; var max_rows = sht.UsedRange.Rows.Count,max_cols = sht.UsedRange.Columns.Count; // 获取总表的数据区域 rng = sht.Range(sht.Cells(title_row, 1), sht.Cells(max_rows, max_cols)); if(title_row>1){ // 获取标题行前面的区域 start = sht.Range(sht.Cells(1, 1), sht.Cells(title_row-1, max_cols)); } // 读取表头名称 let header = sht.Range(sht.Cells(title_row, 1), sht.Cells(title_row, max_cols)).Value2[0]; 文末有福利领取哦~
👉一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
👉二、Python必备开发工具
👉三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
👉 四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(文末领读者福利)
👉五、Python练习题
检查学习结果。
👉六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传