最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python對Excel工作簿中的所有工作表分別求和并自動生成結(jié)果

 更新時間:2026年06月30日 08:46:24   作者:楊利杰YJlio  
本文介紹了如何用Python自動對Excel工作簿中的所有工作表進行求和匯總,通過遍歷每個工作表,識別金額列并計算合計值,腳本會在每張表末尾追加合計行,并生成一個匯總表集中展示所有結(jié)果,有需要的小伙伴可以了解下

1. 問題背景:幾十個 Sheet 都要合計,手工做很痛苦

這一篇繼續(xù)整理《超簡單:用 Python 讓 Excel 飛起來》第 6 章中的案例內(nèi)容,主題是 對一個工作簿中的所有工作表分別求和。這個場景非常貼近真實辦公:一個 Excel 工作簿里按月份、部門、項目或區(qū)域拆了很多 Sheet,每張表結(jié)構(gòu)類似,都有一列金額,現(xiàn)在需要分別計算每張表的合計值。

手工當然也能做。打開第一張表,找到金額列,寫一個 SUM;再打開第二張表,重復一次;幾十張表下來,本質(zhì)就是重復點鼠標、重復復制公式、重復檢查結(jié)果。表少的時候還能忍,表一多就容易漏算、錯算、重復算。

這張圖展示了本文的整體主題:使用 Python 對一個工作簿中的所有工作表分別求和,并自動生成結(jié)果。

從這張圖中可以看出,本文的重點不是單獨計算某一個 Sheet,而是把“遍歷所有 Sheet → 指定列求和 → 寫回合計結(jié)果 → 生成匯總表”做成一條完整自動化流程。真正有價值的不是 sum() 這一個函數(shù),而是把求和任務變成可重復執(zhí)行的批處理模板。

這里最容易犯的錯誤,是把這個案例理解成簡單求和。實際工作中更麻煩的是:有的 Sheet 是空表,有的 Sheet 缺少目標列,有的金額看起來是數(shù)字,其實是文本,還有的工作簿已經(jīng)存在“匯總”Sheet。腳本要能處理這些邊界,才算真正可用。

2. 目標效果:運行一次腳本想看到什么

這個案例的目標效果可以拆成兩層。第一層是在每張業(yè)務工作表底部自動追加一行 合計,并把指定金額列的合計值寫進去。第二層是額外生成一個 匯總 工作表,把每張 Sheet 的合計結(jié)果集中展示出來。

這張圖展示了第一層效果:腳本會在每張工作表底部自動寫入合計行。

從這張圖中可以看出,合計結(jié)果不是覆蓋原始數(shù)據(jù),而是追加在表格末尾。這個設(shè)計比較穩(wěn),因為原數(shù)據(jù)結(jié)構(gòu)不會被破壞,讀者打開每張表時,也能直接看到該表自己的合計結(jié)果。

推薦把合計結(jié)果寫在表尾,而不是直接插入到數(shù)據(jù)中間。這樣既方便閱讀,也減少破壞原有數(shù)據(jù)結(jié)構(gòu)的風險。如果后續(xù)要再次處理原始明細,表尾合計行也更容易識別和排除。

最終我們希望得到這樣的交付結(jié)果:

1. 每張業(yè)務 Sheet:

  • 表尾追加“合計”行
  • 指定金額列寫入合計值

2. 匯總 Sheet:

  • 列出每張工作表名稱
  • 列出每張表的金額合計
  • 最后一行給出總計

這套輸出適合交付領(lǐng)導或業(yè)務同事:既能看每張表的局部結(jié)果,也能在匯總表里橫向?qū)Ρ人?Sheet。

3. 實現(xiàn)思路:把求和變成標準化流水線

要想讓腳本穩(wěn)定,就不能只盯著“求和”這一步。完整流程應該是:打開工作簿,遍歷所有工作表,讀取表格數(shù)據(jù),清洗金額列,計算合計,寫回當前 Sheet,記錄到匯總列表,最后生成匯總 Sheet 并保存。

這張圖展示了自動求和的完整流程,從打開工作簿到生成匯總表,每一步都對應腳本中的關(guān)鍵動作。

從這張圖中可以看出,一個可靠的自動化腳本必須具備“遍歷、清洗、計算、寫回、匯總”五個動作。如果缺少清洗,金額可能算錯;如果缺少寫回,單表結(jié)果不直觀;如果缺少匯總,領(lǐng)導仍然看不到整體對比。

我把這一節(jié)理解成一個可復用模塊。輸入是工作簿路徑和要合計的列名,輸出是每個 Sheet 的合計行和一個總匯總表。后續(xù)如果要計算最大值、最小值、平均值,其實也能沿用同一套框架,只是把計算函數(shù)換掉。

4. 環(huán)境準備:pandas 負責計算,xlwings 負責寫回 Excel

這個案例里我使用的組合是 pandas + xlwings。其中 pandas 負責數(shù)據(jù)讀取后的計算和清洗,xlwings 負責打開工作簿、遍歷工作表、把結(jié)果寫回 Excel。

pandas 擅長算數(shù)據(jù),xlwings 擅長操作 Excel 應用。這兩個工具組合在一起,適合處理這種“既要計算,又要寫回原工作簿結(jié)構(gòu)”的任務。

安裝命令如下:

pip install pandas xlwings

如果你的電腦沒有安裝 Excel,或者 Excel 被安全策略、加載項、彈窗卡住,xlwings 可能無法正常工作。這不是 Python 語法問題,而是 Excel 應用環(huán)境問題。在企業(yè)桌面環(huán)境中,這一點要提前確認。

推薦先復制一份測試工作簿,不要直接對正式文件運行腳本。尤其是腳本涉及寫回、保存、另存為這些動作時,先用樣本文件跑通,再處理正式數(shù)據(jù)。

5. 完整代碼:對所有 Sheet 分別求和并生成匯總表

下面這份代碼是一個相對完整的版本,重點考慮了幾個真實場景:自動跳過空表,自動跳過缺少目標列的 Sheet,自動跳過 匯總 Sheet,金額列支持 ¥12,345.67 這類文本數(shù)字,寫回時只在表尾追加合計行,不覆蓋原始明細數(shù)據(jù)。

import pandas as pd
import xlwings as xw


def clean_to_number(s: pd.Series) -> pd.Series:
    """
    把帶貨幣符號、逗號、空格的文本金額轉(zhuǎn)換成數(shù)值。
    例如:¥12,345.67 -> 12345.67
    """
    s = s.astype(str).str.strip()
    s = s.str.replace(",", "", regex=False)
    s = s.str.replace(r"[¥¥$ ]", "", regex=True)
    s = s.str.replace(r"[^0-9\.\-]", "", regex=True)
    return pd.to_numeric(s, errors="coerce")


def sum_all_sheets_in_workbook(
    input_xlsx: str,
    sum_col: str = "銷售利潤",
    summary_sheet_name: str = "匯總",
    start_cell: str = "A1",
    save_as: str | None = None,
) -> None:
    """
    對一個工作簿中的所有工作表分別對 sum_col 求和:
    1. 在每個 Sheet 末尾追加“合計”行
    2. 生成或覆蓋一個“匯總”Sheet,列出每個 Sheet 的合計和總計

    save_as=None:覆蓋保存原文件
    save_as=路徑:另存為新文件
    """

    app = xw.App(visible=False, add_book=False)
    app.display_alerts = False
    app.screen_updating = False

    try:
        wb = app.books.open(input_xlsx)
        results = []

        for sht in wb.sheets:

            # 跳過匯總 Sheet,避免二次運行時把匯總表也拿去求和
            if sht.name == summary_sheet_name:
                continue

            rng = sht.range(start_cell).expand("table")

            if rng.value is None:
                print(f"[SKIP] {sht.name}: 空表")
                continue

            df = rng.options(pd.DataFrame).value

            if df is None or df.empty:
                print(f"[SKIP] {sht.name}: 無有效數(shù)據(jù)")
                continue

            if sum_col not in df.columns:
                print(f"[SKIP] {sht.name}: 缺少列 '{sum_col}'")
                continue

            # 清洗金額列并求和
            num = clean_to_number(df[sum_col]).fillna(0)
            total = float(num.sum())

            # 寫回:在當前表格最后一行下面追加合計行
            last_cell = rng.last_cell
            total_row = last_cell.row + 1

            # 找到 sum_col 在表格中的列序號,xlwings 使用 1-based 列號
            col_idx = df.columns.get_loc(sum_col) + 1

            sht.range((total_row, 1)).value = "合計"
            sht.range((total_row, col_idx)).value = total

            # 給合計行加粗,便于閱讀
            try:
                sht.range((total_row, 1), (total_row, col_idx)).api.Font.Bold = True
            except Exception:
                pass

            results.append({
                "工作表": sht.name,
                f"{sum_col}合計": total
            })

            print(f"[OK] {sht.name}: {sum_col} 合計 = {total}")

        # 生成匯總 Sheet
        summary_df = pd.DataFrame(results)

        if summary_df.empty:
            raise RuntimeError("未得到任何可匯總結(jié)果,請檢查列名、數(shù)據(jù)區(qū)域或是否為空表。")

        total_col = f"{sum_col}合計"
        grand_total = float(summary_df[total_col].sum())

        summary_df = summary_df.sort_values(by=total_col, ascending=False)

        # 如果已存在匯總 Sheet,則清空;不存在則新建
        try:
            sum_sht = wb.sheets[summary_sheet_name]
            sum_sht.clear()
        except Exception:
            sum_sht = wb.sheets.add(summary_sheet_name, before=wb.sheets[0])

        sum_sht.range("A1").options(index=False).value = summary_df

        # 寫入總計
        last = sum_sht.range("A1").expand("table").last_cell
        total_row = last.row + 1

        sum_sht.range((total_row, 1)).value = "總計"
        sum_sht.range((total_row, 2)).value = grand_total

        try:
            sum_sht.range((1, 1), (total_row, 2)).api.Columns.AutoFit()
            sum_sht.range((total_row, 1), (total_row, 2)).api.Font.Bold = True
        except Exception:
            pass

        if save_as:
            wb.save(save_as)
            print(f"[DONE] 已另存為:{save_as}")
        else:
            wb.save()
            print(f"[DONE] 已覆蓋保存:{input_xlsx}")

        wb.close()

    finally:
        app.quit()


if __name__ == "__main__":
    sum_all_sheets_in_workbook(
        input_xlsx="產(chǎn)品銷售統(tǒng)計表.xlsx",
        sum_col="銷售利潤",
        summary_sheet_name="匯總",
        start_cell="A1",
        save_as="產(chǎn)品銷售統(tǒng)計表_已求和.xlsx",
    )

這份代碼的結(jié)構(gòu)并不復雜,但邊界處理比較重要。它不是簡單讀取所有 Sheet 后直接求和,而是先排除匯總表,再判斷是否為空表,再判斷目標列是否存在,最后才進入金額清洗和求和邏輯。

如果你直接把所有 Sheet 都拿來求和,下一次運行腳本時,匯總表也可能被重復計算,結(jié)果會越來越怪。所以跳過 summary_sheet_name 不是錦上添花,而是必須保留的安全判斷。

6. 關(guān)鍵點拆解:金額列看著像數(shù)字,其實可能是字符串

這個案例最容易翻車的地方,不是 sum() 不會用,而是金額列的數(shù)據(jù)類型不穩(wěn)定。Excel 里很多金額看起來像數(shù)字,但實際可能是文本,例如 ¥12,345.67、12,345、 8000 ,甚至混有空格和貨幣符號。

這張圖展示了金額清洗的核心過程:把原始金額文本去掉符號、逗號和無效字符,再轉(zhuǎn)換成真正可以求和的數(shù)值。

從這張圖中可以看出,求和前的關(guān)鍵動作是“清洗轉(zhuǎn)換”。如果金額列沒有先轉(zhuǎn)成數(shù)值,腳本可能得到 0、NaN,或者產(chǎn)生錯誤結(jié)果。這類問題表面上像是計算錯誤,實際上是數(shù)據(jù)類型問題。

清洗函數(shù)的核心代碼如下:

def clean_to_number(s: pd.Series) -> pd.Series:
    s = s.astype(str).str.strip()
    s = s.str.replace(",", "", regex=False)
    s = s.str.replace(r"[¥¥$ ]", "", regex=True)
    s = s.str.replace(r"[^0-9\.\-]", "", regex=True)
    return pd.to_numeric(s, errors="coerce")

這段代碼做了四件事:第一,把數(shù)據(jù)統(tǒng)一轉(zhuǎn)成字符串;第二,去掉逗號;第三,去掉人民幣符號、美元符號和空格;第四,只保留數(shù)字、小數(shù)點和負號,再用 pd.to_numeric() 轉(zhuǎn)成數(shù)值。

涉及金額統(tǒng)計時,我建議永遠先做類型清洗,再做求和。不要相信 Excel 里“看起來像數(shù)字”的顯示效果。腳本處理的是底層數(shù)據(jù)類型,不是你眼睛看到的表格樣式。

7. 效果驗證:如何確認腳本真的成功

腳本運行完成,不代表結(jié)果一定正確。對這種批量求和腳本,至少要驗證三件事:每張業(yè)務 Sheet 是否寫入了合計行;匯總 Sheet 是否生成;匯總 Sheet 的總計是否等于各 Sheet 合計之和。

這張圖展示了最終匯總效果:多個工作表的合計結(jié)果集中到一張匯總表中,并可以橫向?qū)Ρ取?/p>

從這張圖中可以看出,匯總表不只是把結(jié)果堆在一起,它還承擔了橫向?qū)Ρ鹊淖饔?。哪個部門、哪個月份、哪個項目金額最高,一眼就能看出來。這才是自動生成匯總表的真正價值:減少人工統(tǒng)計,也減少人工解釋。

建議驗證時按下面幾個點檢查:

1. 打開每個業(yè)務 Sheet,確認表尾是否出現(xiàn)“合計”行

2. 檢查目標金額列是否寫入正確合計值

3. 打開“匯總”Sheet,確認每張表都有一條匯總記錄

4. 檢查“總計”是否等于所有 Sheet 合計之和

5. 抽查 1 到 2 張 Sheet,用 Excel 自帶 SUM 手工核對一次

如果想在腳本中增加簡單驗證,也可以打印每個 Sheet 的處理日志:

print(f"[OK] {sht.name}: {sum_col} 合計 = {total}")

推薦保留控制臺日志。批量腳本不應該靜默運行。哪些 Sheet 成功、哪些 Sheet 跳過、跳過原因是什么,都應該能從日志里看出來。這是后續(xù)復盤和排錯的基礎(chǔ)。

8. 常見問題與踩坑記錄

8.1 expand(“table”) 依賴連續(xù)表格

sht.range(start_cell).expand("table") 的好處是方便,它會從起始單元格自動擴展讀取連續(xù)區(qū)域。但它也有前提:表格中間不能有完全空白行或空白列。

如果你的表格中間有空行,expand 可能讀不全。這種情況下,建議先統(tǒng)一模板,或者改成固定讀取范圍,例如 A1:H2000。

8.2 匯總 Sheet 必須跳過

如果腳本第一次運行后生成了 匯總 Sheet,第二次再運行時,如果不跳過它,腳本可能會把匯總表也當成業(yè)務表繼續(xù)求和。

if sht.name == summary_sheet_name:
    continue

這行代碼非常關(guān)鍵。只要腳本會生成結(jié)果 Sheet,就應該在遍歷時明確跳過結(jié)果 Sheet。

8.3 不要默認每張表都有目標列

真實工作簿里經(jīng)常會出現(xiàn)模板不統(tǒng)一的問題。有的 Sheet 叫 銷售利潤,有的可能叫 利潤 或 銷售金額。如果不判斷列名,腳本會直接報錯。

if sum_col not in df.columns:
    print(f"[SKIP] {sht.name}: 缺少列 '{sum_col}'")
    continue

這個判斷的意義,是讓異常 Sheet 被識別并跳過,而不是讓一個異常 Sheet 中斷整個工作簿的處理。

8.4 不建議直接覆蓋原文件

雖然代碼支持 save_as=None 覆蓋保存原文件,但我不建議初次使用時這么做。尤其是腳本會寫回每張表、生成匯總 Sheet,一旦邏輯有誤,原文件就可能被污染。

推薦使用另存為模式:

save_as="產(chǎn)品銷售統(tǒng)計表_已求和.xlsx"

這樣原始文件不會被破壞,處理結(jié)果也更方便對比。

9. 總結(jié)提升:這節(jié)真正要學的是批量計算框架

這一節(jié)看起來只是對每張工作表求和,但真正值得帶走的是一套批量計算框架:遍歷 Sheet、識別目標列、清洗數(shù)據(jù)、執(zhí)行計算、寫回結(jié)果、生成匯總表、最后驗證輸出。

如果只會寫 sum(),遇到真實辦公數(shù)據(jù)很快就會卡??;如果理解了這套流程,后續(xù)要做最大值、最小值、平均值、按條件求和、多列匯總,其實都是在同一個框架上替換計算邏輯。

辦公自動化腳本的價值,不是讓代碼看起來復雜,而是讓重復動作變得穩(wěn)定、可驗證、可復盤。這一點比單純記住某個函數(shù)更重要。

最后再提醒一次:批量寫回 Excel 前一定要先備份。自動化腳本跑得越快,錯誤擴散得也越快。先用樣本文件測試,確認合計行、匯總表、總計結(jié)果都正確,再處理正式工作簿。

以上就是使用Python對Excel工作簿中的所有工作表分別求和并自動生成結(jié)果的詳細內(nèi)容,更多關(guān)于Python Excel工作表求和的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Django中使用haystack+whoosh實現(xiàn)搜索功能

    Django中使用haystack+whoosh實現(xiàn)搜索功能

    這篇文章主要介紹了Django之使用haystack+whoosh實現(xiàn)搜索功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • 提升Python程序性能的7個習慣

    提升Python程序性能的7個習慣

    這篇文章主要介紹了提升Python程序性能的7個習慣,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • 最新評論

    新邵县| 吉林市| 贵阳市| 民县| 金寨县| 灵石县| 沛县| 永丰县| 宣汉县| 平武县| 阆中市| 玉溪市| 正安县| 淄博市| 磐安县| 武清区| 酒泉市| 旬邑县| 连平县| 东乌珠穆沁旗| 利辛县| 定兴县| 定安县| 黄冈市| 鸡泽县| 万州区| 安远县| 梁河县| 安泽县| 布拖县| 三门县| 长宁县| 乌鲁木齐市| 喜德县| 宣化县| 通州市| 恩施市| 长宁县| 台湾省| 澄江县| 阿拉尔市|