使用 Python 实现 Excel 行列转置(保留单元格样式)

前言

在数据处理场景中,经常会遇到表格行列互换需求:原始横向表格转为纵向,或是纵向指标表转为横向汇总表。手动复制粘贴转置在数据量大、需要自动化重复执行时效率很低。

Python 生态有多种处理 Excel 的方案,本文介绍如何使用免费库 Free Spire.XLS for Python 来实现行列转置。它的优势是不依赖本地安装 Microsoft Excel ,可以直接读写 .xlsx/.xls 文件,并且能够保留单元格样式、格式,而不仅仅是纯文本数据。

⚠️ 说明 :免费版一般适合中小型报表自动化场景,使用前先了解限制,大规模业务场景需要提前评估限制。


环境准备

Python 版本要求:Python3.6+

使用pip安装免费包:

bash 复制代码
pip install Spire.Xls.Free

导入需要用到的模块:

python 复制代码
from spire.xls import Workbook, FileFormat

实现思路

行列转置本质是矩阵转置:原表第i行第j列的数据,写入新区域的第j行第i列。

实现步骤:

  1. 加载Excel文件,读取目标工作表
  2. 获取已使用数据区域,得到有效行数、列数
  3. 遍历原区域,缓存单元格值+样式
  4. 在工作表的空白区域写入转置后的数据,同步复制单元格样式
  5. 保存文件,释放资源

💡 两种可选方案:

① 在同一张工作表空白区域写入转置结果;

② 新建工作表存放转置后数据。

下面示例同一张工作表方案,避免切 sheet 查看,也方便用公式引用原始区域。


完整代码示例

python 复制代码
from spire.xls import Workbook, FileFormat

def transpose_excel(file_path: str, output_path: str):
    # 加载工作簿
    wb = Workbook()
    wb.LoadFromFile(file_path)
    sheet = wb.Worksheets[0]

    # 获取当前工作表已使用范围
    used_range = sheet.AllocatedRange
    row_count = used_range.Rows.Count
    col_count = used_range.Columns.Count

    # 目标空白区域起始位置
    start_row = row_count + 2
    start_col = col_count + 2

    # 遍历原区域,完成行列转置,同时复制单元格样式
    for r in range(1, row_count + 1):
        for c in range(1, col_count + 1):
            src_cell = sheet.Range[r, c]
            # 转置:原r行c列 → 目标(start_row + c - 1, start_col + r - 1) 行/列
            dest_row = start_row + c - 1
            dest_col = start_col + r - 1
            dest_cell = sheet.Range[dest_row, dest_col]
            dest_cell.Value = src_cell.Value
            # 复制单元格样式(字体、边框、背景色等)
            dest_cell.Style = src_cell.Style

    # 保存输出文件
    wb.SaveToFile(output_path, FileFormat.Version2016)
    # 释放资源
    wb.Dispose()
    print(f"转置完成,文件输出至:{output_path}")


if __name__ == "__main__":
    transpose_excel("source.xlsx", "transposed_result.xlsx")

代码关键点解析

  1. AllocatedRange:获取工作表实际占用的单元格区域,避免遍历大量空白单元格,提升执行效率。
  2. 单元格样式复制 :dest_cell.Style = src_cell.Style,这是很多轻量库不具备的能力,可以保留原表格边框、背景色、字体格式。
  3. 资源释放 wb.Dispose():该库底层是非托管资源,脚本结束建议主动释放,避免文件句柄占用。

测试结果

执行脚本后,transposed_result.xlsx 结果文件预览:


扩展:仅转置纯数据(不复制样式,速度更快)

python 复制代码
from spire.xls import Workbook, FileFormat

def transpose_excel_data_only(file_path: str, output_path: str):
    wb = Workbook()
    wb.LoadFromFile(file_path)
    sheet = wb.Worksheets[0]
    used_range = sheet.AllocatedRange
    row_count = used_range.Rows.Count
    col_count = used_range.Columns.Count

    # 读取二维数组
    data = []
    for r in range(1, row_count + 1):
        row_data = []
        for c in range(1, col_count + 1):
            row_data.append(sheet.Range[r, c].Value)
        data.append(row_data)

    # 矩阵转置
    transposed_data = list(zip(*data))

    # 写入原区域正下方的空白区域
    start_row = row_count + 2
    for tr, row in enumerate(transposed_data, start=start_row):
        for tc, val in enumerate(row, start=1):
            sheet.Range[tr, tc].Value = val

    wb.SaveToFile(output_path, FileFormat.Version2016)
    wb.Dispose()

✅ 与 pandas 方案对比

  • pandas :数据转置简单(df.T),但输出过程会重新构建工作表,原有格式(如单元格颜色、边框、列宽)无法保留,适用于纯数据分析场景而非文档格式保真场景。

  • Free Spire.XLS:独立组件,无需 Office,原生支持复制单元格样式。当报表带有复杂格式、边框、背景色需要保留时,这个方案会更省心。


小结

本文通过 Free Spire.XLS for Python 实现 Excel 行列转置,重点演示带样式保留 的场景,适合报表自动化、数据整理脚本开发。核心逻辑就是矩阵转置,通过遍历单元格把(r,c)映射到(c,r)。

相关推荐
WeiXin_DZbishe2 小时前
基于Node.js的马拉松赛事管理系统的设计与实现-计算机毕设 附源码【课程设计】90211
java·javascript·vue.js·python·php·课程设计
西西学代码2 小时前
像素和颜色之间的转换(Flutter)
前端·javascript·flutter
计算机编程指导师2 小时前
计算机毕设选题推荐:基于Spark+Django的黄金价格历史数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·python·计算机·spark·django·课程设计·黄金价格
yi0112 小时前
LeetCode 424. 替换后的最长重复字符|不定长滑动窗口:如何判断窗口是否合法?
笔记·python·算法·leetcode·双指针·滑动窗口
计算机编程指导师2 小时前
计算机毕设怎么做?基于Spark+Django的股票数据分析与可视化系统实战指导 源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·python·spark·django·毕业设计·股票·课程设计
茶底世界之下2 小时前
羽毛颜色已经很鲜艳,还要继续加色吗?用 Awaking 试一次减饱和
前端·ios·运营
高级程序源2 小时前
django房屋租赁系统28636-计算机课程设计、毕业设计
python·mysql·elasticsearch·小程序·django·flask·课程设计
deepseek232 小时前
SQLite WAL 开了仍报 database is locked?Python 后台任务的事务与幂等修复
数据库·python·sqlite·并发编程·wal
风早爽太2 小时前
Mac 搭建 Vue 开发环境
前端·vue.js