From bc1f1fe60d4ce20de619275806483a5d0b07f939 Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期五, 04 九月 2026 20:33:53 +0800
Subject: [PATCH] \ feat: 汇总大表生成支持toMonth裁剪(1-6月生成+1-7月扩列)及验证产物与测试报告\

---
 docs/工作日结/工作日结_2026-09-04.md                                                                            |   11 +++
 docs/功能测试报告/功能测试报告_汇总大表1-6月生成与1-7月扩列验证_2026-09-04.md                                                    |   46 +++++++++++++++
 docs/生成汇总大表/输出/道路运输量汇总表_2026-07.xlsx                                                                    |    0 
 traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java       |   79 ++++++++++++++++++++++++++
 docs/生成汇总大表/输出/道路运输量汇总表_2026-06.xlsx                                                                    |    0 
 traffic-audit-server/src/main/java/com/trafficaudit/reportexport/controller/ReportExportController.java |    5 +
 6 files changed, 138 insertions(+), 3 deletions(-)

diff --git "a/docs/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212_\346\261\207\346\200\273\345\244\247\350\241\2501-6\346\234\210\347\224\237\346\210\220\344\270\2161-7\346\234\210\346\211\251\345\210\227\351\252\214\350\257\201_2026-09-04.md" "b/docs/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212_\346\261\207\346\200\273\345\244\247\350\241\2501-6\346\234\210\347\224\237\346\210\220\344\270\2161-7\346\234\210\346\211\251\345\210\227\351\252\214\350\257\201_2026-09-04.md"
new file mode 100644
index 0000000..51406a2
--- /dev/null
+++ "b/docs/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212_\346\261\207\346\200\273\345\244\247\350\241\2501-6\346\234\210\347\224\237\346\210\220\344\270\2161-7\346\234\210\346\211\251\345\210\227\351\252\214\350\257\201_2026-09-04.md"
@@ -0,0 +1,46 @@
+# 鍔熻兘娴嬭瘯鎶ュ憡锛氭眹鎬诲ぇ琛� 1-6 鏈堢敓鎴� + 1-7 鏈堟墿鍒楋紙2026-09-04锛�
+
+## 涓�銆佸姛鑳借鏄�
+- 鐩爣锛氶獙璇併�婇亾璺繍杈撻噺姹囨�昏〃銆嬬敓鎴愮▼搴忓彲浜у嚭涓ゆ湰浜х墿鈥斺��
+  1. **1-7 鏈堟墿鍒�**锛坄period=2026-07`锛夛細浠モ��1-4 鏈堥鏋垛�濇瘝鐗堜负搴曘�佹寜鍚屾湡澶囦唤姣嶇増杩樺師鏈堝害鍧楋紝寰楀埌 1-7 鏈堝畬鏁村伐浣滅翱锛�
+  2. **1-6 鏈堢敓鎴�**锛坄period=2026-07&toMonth=6`锛夛細鍦ㄤ笂杩� 1-7 鍐呭鍩虹涓婏紝鎶� 8 涓彴璐�/鍚堟垚椤佃鍓埌 6 鏈堚�斺��
+     - 7 鏈堝綋鏈堝�煎垪锛圤锛夈��7 鏈堝悓姣斿垪锛圥锛夌殑**鏁版嵁鏍兼竻绌猴紝琛ㄥご淇濈暀**锛堢敤鎴锋媿鏉垮彛寰� 鈶狅級锛�
+     - 绱鍏紡锛圦锛夊幓鎺� 7 鏈堥」锛岀疮璁″悓姣斿叕寮忥紙R锛夊垎姣嶅幓鎺� 2025 骞� 7 鏈堝垪锛�=2025 骞� 1-6 鏈堬紝鐢ㄦ埛鎷嶆澘鍙e緞 鈶★級銆�
+- 浠g爜鏀瑰姩锛�
+  - `ReportExportService.exportSummaryWorkbook(period, mode, toMonth)`锛氭柊澧炲彲閫� `toMonth` 瑁佸壀锛�
+  - 鏂板 `trimSummaryMonthlySheets(wb, keepMonths)`锛氬彧澶勭悊 8 涓彴璐�/鍚堟垚椤碉紙` 璐ц繍`銆佺彮绾垮寘杞︺�佸煄甯傚杩愩�佸叕浜ゃ�佸嚭绉熴�佺綉绾﹁溅銆佽建閬撱�佽疆娓°�佷腑鍙e緞鏄庣粏锛夛紝鎸夆�滃惈绱鍏紡涓斾换涓� 2026 鏈堝害鍊煎垪闈炵┖鈥濊瘑鍒暟鎹锛�
+  - `ReportExportController /export/summaryWorkbook` 澧炲姞鍙�夊弬鏁� `toMonth`銆�
+- 浜х墿锛堢▼搴忓疄闄� HTTP 鐢熸垚锛岄潪鎵嬪伐鏀硅〃锛夛細
+  - `docs/鐢熸垚姹囨�诲ぇ琛�/杈撳嚭/閬撹矾杩愯緭閲忔眹鎬昏〃_2026-07.xlsx`锛�921,070 B锛�
+  - `docs/鐢熸垚姹囨�诲ぇ琛�/杈撳嚭/閬撹矾杩愯緭閲忔眹鎬昏〃_2026-06.xlsx`锛�912,980 B锛�
+
+## 浜屻�佹祴璇曠幆澧�
+- 鍚庣 Spring Boot 8090锛坄mvn spring-boot:run` 瀹炶窇锛屾湰鏈� MySQL 127.0.0.1:3308/traffic_audit锛夛紱
+- 姣嶇増锛歚docs/鐢熸垚姹囨�诲ぇ琛�/2026骞�7鏈堥亾璺繍杈撻噺姹囨�昏〃.xlsx`锛�1-4 鏈堥鏋讹紝宸ヤ綔鍖烘湭鎻愪氦鐗堬級锛�
+- 澶囦唤姣嶇増锛堥�愭牸瀵圭収鍩哄噯锛夛細`docs/鐢熸垚姹囨�诲ぇ琛�/_澶囦唤_2026骞�7鏈堥亾璺繍杈撻噺姹囨�昏〃_娓呯悊鍓峗20260904.xlsx`锛�
+- 鏍¢獙鑴氭湰锛氶�愭牸姣旇緝鍗曞厓鏍煎師鏂囷紙鍏紡鍚� `=`銆佸�笺�佹枃鏈級锛屾暟鍊兼寜 int/float 绛変环褰掍竴鍖栥��
+
+## 涓夈�佺敤渚嬩笌缁撴灉
+
+| # | 鐢ㄤ緥 | 杈撳叆 | 棰勬湡 | 瀹為檯 | 缁撹 |
+|---|---|---|---|---|---|
+| 1 | 1-7 鏈堟墿鍒� | GET `/api/report/export/summaryWorkbook?period=2026-07&mode=month` | 涓庡浠芥瘝鐗堝叏绨块�愭牸涓�鑷� | 鐪熷樊寮�=0 | 閫氳繃 |
+| 2 | 1-6 鏈堢敓鎴愶紙姝e悜锛� | 鍚屼笂杩藉姞 `&toMonth=6` | 闈炶鍓寖鍥达紙闈� 8 鍙拌处椤� + 8 鍙拌处椤� A..N 绛夛級涓庡浠戒竴鑷达紱浠� O/P/Q/R 鎸夎鍒欏彉鍖� | 闈炵櫧鍚嶅崟鐪熷樊寮�=0 | 閫氳繃 |
+| 3 | 7 鏈堜袱鍒楁竻绌�/琛ㄥご淇濈暀 | 8 鍙拌处椤垫暟鎹 O/P | 鏁版嵁鏍肩┖銆佽〃澶磋 O/P 淇濈暀 | 鏁版嵁鏍兼竻绌� 1132锛岃〃澶翠繚鐣� 24锛岃〃澶村紓甯� 0 | 閫氳繃 |
+| 4 | 绱鎸� 1-6 鏈� | 鏁版嵁琛� Q 鍒楀叕寮� | 鍘绘帀 `+O{琛寎` | 鏀瑰啓 566 澶勶紝渚嬶細`=C5+E5+...+O5`鈫抈=C5+...+M5` | 閫氳繃 |
+| 5 | 绱鍚屾瘮鍒嗘瘝=2025 1-6 鏈� | 鏁版嵁琛� R 鍒楀叕寮� | 鍘绘帀 `,AF{琛寎`/`+AF{琛寎` | 鏀瑰啓 566 澶勶紝渚嬶細`=Q5/SUM(T5..AF5)-1`鈫抈=Q5/SUM(T5..AD5)-1` | 閫氳繃 |
+| 6 | 鎶芥煡鍏抽敭鏍� | 璐ц繍/涓彛寰勬槑缁� O/P/Q/R | 琛ㄥご瑙佹枃銆佹暟鎹 O/P 绌� | 07 鏁版嵁琛� O=3754.7823锛�7 鏈堝�硷級锛�06 鍚屾牸涓虹┖锛涜〃澶翠竴鑷� | 閫氳繃 |
+| 7 | 璐熷悜/杈圭晫 | `toMonth` 缂虹渷鎴� 鈮�7 | 琛屼负涓庢棫鐗堜竴鑷达紙鍏ㄧ翱杩樺師锛� | 鍚岀敤渚� 1锛岀湡宸紓 0 | 閫氳繃 |
+
+## 鍥涖�佸疄鐜颁腑鍙戠幇骞跺缃殑闂
+1. **POI 琛屽彿 0-based vs 鍏紡 1-based**锛氬垵鐗堟寜琛岀储寮曟嫾鎺� `+O4`锛屽尮閰嶄笉涓婂叕寮忛噷鐨� `O5`锛屽鑷� Q/R 鏈敼鍐欙紙浠呮竻绌虹敓鏁堬級銆傚缃細token 琛屽彿鏀� `excelRow = r + 1`銆�
+2. **2025 鍚屾湀鍒� 0-based 绱㈠紩閿� 1**锛氬垎姣嶅垪 T..AF 鐨� 0-based 璧风偣鏄� 19锛圱锛夛紝璇敤 20 浼氱畻鍑� AG锛堝垪鍙疯秺 1 鍒楋級锛孯 鍏紡鍖归厤涓嶅埌銆傚缃細`lastCol = 19 + 2*(m-1)`銆�
+3. 涓ゅ淇鍚庡潎閲嶆柊 `mvn compile` + 閲嶅惎鍚庣澶嶆祴閫氳繃锛堟渶缁堜骇鐗╀负淇鍚庝唬鐮佺敓鎴愶級銆�
+
+## 浜斻�佽竟鐣屼笌宸茬煡椤癸紙鏈鏈撼鍏ワ級
+- **鎴愬搧鑱氬悎椤�**锛堣揣杩愰噺鎺掑悕銆佽揣杩愬懆杞噺鎺掑悕銆佷腑鍙e緞鎺掑悕銆佷腑鍙e緞鍒嗘瀽銆佸煄甯傛眹鎬汇�佸煄甯傚垎甯傚窞銆侀亾璺繍杈撳懆杞噺锛夌殑鍗曞厓鏍间负**浜哄伐姣嶇増闈欐�佸�硷紙1-7 鏈堢疮璁″彛寰勶級**锛屾湰娆¤鍓笉瑙﹀強锛涜闅忊��1-6 鏈堚�濊嚜鍔ㄩ噸绠楅渶璧� P2-P5 鏁版嵁椹卞姩濉厖锛堝彟鎺掓湡锛夈��
+- 2025/2024 鍙傝�冨垪淇濈暀姣嶇増缂撳瓨鍊硷紝鏈敼锛堝凡纭鍙e緞锛夈��
+- 闅愯棌椤碉紙鍏矾鎬诲杩愩��2025骞村煄甯傚杩愰噺銆佷腑鍙e緞瀹㈣繍閲忋�佷腑鍙e緞璁$畻杩囩▼锛夋湭绾冲叆瑁佸壀锛屼繚鎸佸師鏍枫��
+
+## 鍏�佺粨璁�
+鈥滃厛鐢熸垚 1-6 鏈堛��1-7 鏈堟墿鍒椻�濅袱鏈骇鐗╃粡绋嬪簭瀹為檯鐢熸垚骞堕�氳繃閫愭牸瀵圭収锛�1-7 鏈堜骇鐗╀笌澶囦唤姣嶇増闆跺樊寮傦紱1-6 鏈堜骇鐗╁湪 8 涓彴璐�/鍚堟垚椤垫纭墽琛屸��7 鏈堜袱鍒楃暀绌猴紙琛ㄥご淇濈暀锛夈�佺疮璁�/鍚屾瘮鎸� 1-6 鏈堚�濈殑鍙e緞锛屽叾浣欒寖鍥撮浂宸紓銆侾0 椤瑰彲鍏抽棴锛屽墿浣欐垚鍝佽仛鍚堥〉鏁版嵁椹卞姩閲嶇畻锛圥2-P5锛夊崟鍒楄窡杩涖��
diff --git "a/docs/\345\267\245\344\275\234\346\227\245\347\273\223/\345\267\245\344\275\234\346\227\245\347\273\223_2026-09-04.md" "b/docs/\345\267\245\344\275\234\346\227\245\347\273\223/\345\267\245\344\275\234\346\227\245\347\273\223_2026-09-04.md"
index a2f86f8..c0e7e42 100644
--- "a/docs/\345\267\245\344\275\234\346\227\245\347\273\223/\345\267\245\344\275\234\346\227\245\347\273\223_2026-09-04.md"
+++ "b/docs/\345\267\245\344\275\234\346\227\245\347\273\223/\345\267\245\344\275\234\346\227\245\347\273\223_2026-09-04.md"
@@ -13,7 +13,7 @@
 3. 鏂囨。锛氭暟鎹鍏ョ幇鐘朵笌缂哄彛娓呭崟銆佹瘝鐗堜綋妫�娓呭崟杩藉姞鎷嶆澘璁板綍銆佸姛鑳芥祴璇曟姤鍛娒�3銆�
 
 ## 閬楃暀闂涓庡緟鍔烇紙鏄庢棭浼樺厛锛�
-- P0 姹囨�诲ぇ琛ㄢ��1-6 鏈堢敓鎴� + 1-7 鏈堟墿鍒椻�濈▼搴忔敼閫犱笌瀵圭収楠岃瘉锛堢敤鎴峰凡纭 鈶� 绱/鍚屾瘮鎸� 1-6 鏈堛�佸垎姣� 2025 1-6 鏈堬紱鈶� 7 鏈堜袱鍒椾繚鐣欒〃澶淬�佹暟鎹暀绌猴紱濡傛晥鏋滀笉浣冲啀鏀规暣鍒楀幓鎺夛級銆�
+- ~~P0 姹囨�诲ぇ琛ㄢ��1-6 鏈堢敓鎴� + 1-7 鏈堟墿鍒椻�濈▼搴忔敼閫犱笌瀵圭収楠岃瘉~~锛堝凡瀹屾垚锛岃鏂囨湯鈥滄櫄闂磋拷鍔犫�濓紝2026-09-04 澶滐級銆�
 - P1 鍩庡競瀹㈣繍鍏氦/鍑虹鈥滃悓浜嬬増妯℃澘鈥濆垪浣嶅吋瀹癸紙绛夊悓浜嬫枃浠舵垨琛ㄥご锛夈��
 - P1 姣嶇増淇锛堟柟妗� A锛氬綋鏈堝潡閿欑敤绱鍊笺�佸彸渚� #REF! 娓呯悊锛夊悗鍐嶄綔涓烘瘝鐗堬紱docs/鐢熸垚姹囨�诲ぇ琛� 涓嬫湭鎻愪氦鐨� xlsx 鏀瑰姩寰呬竴骞跺鐞嗐��
 - P2 缃戠害杞︽媶鍒�/姹囨�诲伐浣滅翱鐢熸垚鎺ュ叆鍓嶇閫夐」锛堝灏氭湭瀹屾垚锛夛紱鐢熸垚浜х墿鍛藉悕涓庤緭鍑虹洰褰曠‘璁ゃ��
@@ -22,3 +22,12 @@
 ## 澶囨敞
 - 瀹℃牳缁撴灉宸叉寜鏂板彛寰勯噸绠楋紙2026-07 H2032锛夛紱濡備箣鍚庣户缁噸瀵� 07 鎷嗗垎/鍏ㄥ彛寰勶紝闇�鍐嶇偣涓�娆♀�滃鏍糕�濆埛鏂般��
 - 浠婃棩鏈畬鎴愰」涓嶅垹鐢ㄦ埛涓存椂鏂囦欢锛涗复鏃惰剼鏈暀鍦ㄤ粨搴撴牴鐩綍锛坃*.py/_*.sql 绛夛級鏈竻鐞嗐��
+
+## 鏅氶棿杩藉姞锛�2026-09-04 20:3x锛屽姞鐝畬鎴� P0锛�
+- P0銆�1-6 鏈堢敓鎴� + 1-7 鏈堟墿鍒椼�嶇▼搴忔敼閫犱笌瀵圭収楠岃瘉宸插畬鎴愶細
+  - 浠g爜锛歚ReportExportService.exportSummaryWorkbook` 澧炲姞鍙�� `toMonth` 瑁佸壀 + `trimSummaryMonthlySheets`锛�8 鍙拌处/鍚堟垚椤碉細7 鏈堝綋鏈堝��/鍚屾瘮鏁版嵁鏍兼竻绌恒�佽〃澶翠繚鐣欙紝Q 绱鍘� 7 鏈堥」銆丷 绱鍚屾瘮鍒嗘瘝鍘� 2025 骞� 7 鏈堝垪锛夛紱鎺у埗鍣� `/export/summaryWorkbook` 澧炲姞 `toMonth` 鍙傛暟銆�
+  - 浜х墿锛堢▼搴� HTTP 瀹炶窇鐢熸垚锛屽凡钀界洏锛夛細`docs/鐢熸垚姹囨�诲ぇ琛�/杈撳嚭/閬撹矾杩愯緭閲忔眹鎬昏〃_2026-07.xlsx`銆乣_2026-06.xlsx`銆�
+  - 楠岃瘉锛�07 涓庡浠芥瘝鐗堝叏绨块�愭牸 0 宸紓锛�06 闈炵櫧鍚嶅崟 0 宸紓銆丱/P 鏁版嵁娓呯┖ 1132 鏍笺�丵/R 鍏紡鍚勬敼鍐� 566 澶勩�佽〃澶翠繚鐣� 24 鏍煎叏瀵广�傛姤鍛婏細`docs/鍔熻兘娴嬭瘯鎶ュ憡/鍔熻兘娴嬭瘯鎶ュ憡_姹囨�诲ぇ琛�1-6鏈堢敓鎴愪笌1-7鏈堟墿鍒楅獙璇乢2026-09-04.md`銆�
+  - 閬楃暀锛堟柊锛夛細鎴愬搧鑱氬悎椤碉紙鎺掑悕/姹囨��/鍒嗘瀽/鎬诲懆杞噺锛変负姣嶇増闈欐�� 1-7 鍙e緞锛岄渶 P2-P5 鏁版嵁椹卞姩濉厖鍚庡啀绾冲叆 1-6 楠屾敹銆�
+- 鏄庢棩寰呭姙鏇存柊锛歅0 宸蹭粠娓呭崟绉婚櫎锛汸1锛堝悓浜嬬増鍏氦/鍑虹妯℃澘鍒椾綅鍏煎銆佹瘝鐗堟柟妗� A 淇鍚庢彁浜ら鏋舵瘝鐗堜笌涓ゆ湰 xlsx 鍙樻洿锛変繚鎸侊紱P2锛堟垚鍝佽仛鍚堥〉閲嶇畻銆佹眹鎬诲伐浣滅翱鍓嶇鎺ュ叆锛夎窡杩涖��
+
diff --git "a/docs/\347\224\237\346\210\220\346\261\207\346\200\273\345\244\247\350\241\250/\350\276\223\345\207\272/\351\201\223\350\267\257\350\277\220\350\276\223\351\207\217\346\261\207\346\200\273\350\241\250_2026-06.xlsx" "b/docs/\347\224\237\346\210\220\346\261\207\346\200\273\345\244\247\350\241\250/\350\276\223\345\207\272/\351\201\223\350\267\257\350\277\220\350\276\223\351\207\217\346\261\207\346\200\273\350\241\250_2026-06.xlsx"
new file mode 100644
index 0000000..b1a50bb
--- /dev/null
+++ "b/docs/\347\224\237\346\210\220\346\261\207\346\200\273\345\244\247\350\241\250/\350\276\223\345\207\272/\351\201\223\350\267\257\350\277\220\350\276\223\351\207\217\346\261\207\346\200\273\350\241\250_2026-06.xlsx"
Binary files differ
diff --git "a/docs/\347\224\237\346\210\220\346\261\207\346\200\273\345\244\247\350\241\250/\350\276\223\345\207\272/\351\201\223\350\267\257\350\277\220\350\276\223\351\207\217\346\261\207\346\200\273\350\241\250_2026-07.xlsx" "b/docs/\347\224\237\346\210\220\346\261\207\346\200\273\345\244\247\350\241\250/\350\276\223\345\207\272/\351\201\223\350\267\257\350\277\220\350\276\223\351\207\217\346\261\207\346\200\273\350\241\250_2026-07.xlsx"
new file mode 100644
index 0000000..fe4bdb8
--- /dev/null
+++ "b/docs/\347\224\237\346\210\220\346\261\207\346\200\273\345\244\247\350\241\250/\350\276\223\345\207\272/\351\201\223\350\267\257\350\277\220\350\276\223\351\207\217\346\261\207\346\200\273\350\241\250_2026-07.xlsx"
Binary files differ
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/controller/ReportExportController.java b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/controller/ReportExportController.java
index 1dc3efa..efe7696 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/controller/ReportExportController.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/controller/ReportExportController.java
@@ -87,9 +87,10 @@
     /** 鐢熸垚_閬撹矾杩愯緭閲忔眹鎬昏〃.xlsx锛堟眹鎬诲伐浣滅翱 P0-P1 楠ㄦ灦锛氭暣鏈鍒舵瘝鐗堬紝椤电/鍏紡/2025 缂撳瓨淇濈暀锛� */
     @GetMapping("/export/summaryWorkbook")
     public ResponseEntity<byte[]> exportSummaryWorkbook(@RequestParam("period") String period,
-                                                        @RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
+                                                        @RequestParam(value = "mode", defaultValue = "month") String mode,
+                                                        @RequestParam(value = "toMonth", required = false) Integer toMonth) throws Exception {
         logExport("閬撹矾杩愯緭閲忔眹鎬昏〃.xlsx", period);
-        return buildResponse(reportService.exportSummaryWorkbook(period, mode), String.format("鐢熸垚_閬撹矾杩愯緭閲忔眹鎬昏〃_%s.xlsx", period));
+        return buildResponse(reportService.exportSummaryWorkbook(period, mode, toMonth), String.format("鐢熸垚_閬撹矾杩愯緭閲忔眹鎬昏〃_%s.xlsx", period));
     }
 
     /** 鐢熸垚_缃戠害杞﹀杩愰噺鎷嗗垎琛�.xlsx锛堟湀搴︼細璁㈠崟闄勪欢1 + 鍏ㄧ渷 pin + 宸℃父鍑虹鏈堟姤锛� */
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
index 9fe6cae..9fdb6f2 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
@@ -3199,6 +3199,14 @@
      * 淇濈暀鍏ㄩ儴椤电/鐗堝紡/鍏紡/2025 骞寸紦瀛樺�硷紝浠呮妸琛ㄥご骞翠唤鍔ㄦ�佸寲涓虹洰鏍囧勾锛涙暟鎹~鍏呮寜 P2 璧烽�愭鎺ュ叆銆�
      */
     public byte[] exportSummaryWorkbook(String period, String mode) throws Exception {
+        return exportSummaryWorkbook(period, mode, null);
+    }
+
+    /** 鐢熸垚_閬撹矾杩愯緭閲忔眹鎬昏〃.xlsx锛圥0-P1 楠ㄦ灦锛屾敮鎸� toMonth 瑁佸壀锛夛細
+     *  浠ャ�奩YYY骞碝鏈堥亾璺繍杈撻噺姹囨�昏〃.xlsx銆嬶紙M 鐢� period 鍐冲畾锛変负姣嶇増锛屾寜鍚屾湡澶囦唤姣嶇増杩樺師鏈堝害鍧楋紱
+     *  toMonth 闈炵┖涓斿皬浜� M 鏃讹紝鎶� 8 涓彴璐�/鍚堟垚椤佃鍒� toMonth 鏈堬紙toMonth+1..M 鐨勫綋鏈堝��/鍚屾瘮鍒楁竻绌恒�佷繚鐣欒〃澶达紝
+     *  绱涓庣疮璁″悓姣斿叕寮忔敼涓烘寜 toMonth 鏈堥噸绠楋級锛岀敤浜庘�滃厛鐢熸垚 1-6 鏈堛��1-7 鏈堟墿鍒椻�濋獙璇併�� */
+    public byte[] exportSummaryWorkbook(String period, String mode, Integer toMonth) throws Exception {
         int year = Integer.parseInt(period.contains("-") ? period.split("-")[0] : period);
         int month = period.contains("-") ? monthOf(period, mode) : 12;
         File template = resolveSummaryMother(period, mode);
@@ -3215,6 +3223,10 @@
                 }
             } else {
                 log.warn("姹囨�诲伐浣滅翱鏈壘鍒板悓鏈熷浠芥瘝鐗堬紙_澶囦唤_{}骞磠}鏈堚�︼級锛岃緭鍑哄皢淇濇寔姣嶇増鐜扮姸锛堝彲鑳戒负 1-4 鏈堥鏋讹級", year, month);
+            }
+            if (toMonth != null && toMonth > 0 && toMonth < month) {
+                int trimmed = trimSummaryMonthlySheets(wb, toMonth);
+                log.info("姹囨�诲伐浣滅翱瑁佸壀鑷� {} 鏈堝畬鎴愶紝娓呯┖/鏀瑰啓鍗曞厓鏍兼暟={}", toMonth, trimmed);
             }
             dynamicSummaryYear(wb, year);
             applyTwoDecimalFormat(wb); // 姹囨�诲ぇ琛ㄤ繚鐣欎汉宸ユ瘝鐗堝垪瀹�/鐗堝紡锛氫笉鍋� autoFit锛堥暱鍏紡浼氭妸鍒楀椤剁垎锛�
@@ -3566,6 +3578,73 @@
                 return "";
         }
     }
+
+    /** 鎶� 8 涓彴璐�/鍚堟垚椤佃鍓埌 keepMonths 鏈堬細
+     *  鏈堝害鍊煎垪 2026 骞� m 鏈� = 绗� 3+2*(m-1) 鍒楋紙C/E/G/I/K/M/O锛夛紝鍚屾瘮鍒椾负鍏跺悗涓�鍒楋紱
+     *  绱 Q 鍒� = C+E+...+O锛岀疮璁″悓姣� R 鍒楀垎姣� = 2025 骞村悓鏈堝垪 T/V/X/Z/AB/AD/AF銆�
+     *  瑁佸壀 = 鏁版嵁琛岋紙鍚疮璁″叕寮忎笖浠讳竴 2026 鏈堝害鍒楁湁鍐呭锛変腑 keepMonths+1..7 鏈堢殑褰撴湀鍊�/鍚屾瘮鍗曞厓鏍兼竻绌猴紙琛ㄥご淇濈暀锛夛紝
+     *  骞舵妸璇ヨ绱鍏紡鍘绘帀瀵瑰簲 +鍒楋紝绱鍚屾瘮鍒嗘瘝鍘绘帀瀵瑰簲 2025 鍒椼�� */
+    private int trimSummaryMonthlySheets(XSSFWorkbook wb, int keepMonths) {
+        String[] scope = {" 璐ц繍", "鐝嚎鍖呰溅", "鍩庡競瀹㈣繍", "鍏氦", "鍑虹", "缃戠害杞�", "杞ㄩ亾銆佽疆娓�", "涓彛寰勬槑缁�"};
+        java.util.Set<String> scopeSet = new java.util.HashSet<>();
+        for (String s : scope) scopeSet.add(s);
+        int touched = 0;
+        for (int i = 0; i < wb.getNumberOfSheets(); i++) {
+            Sheet sh = wb.getSheetAt(i);
+            if (sh == null || !scopeSet.contains(sh.getSheetName())) continue;
+            for (int r = sh.getFirstRowNum(); r <= sh.getLastRowNum(); r++) {
+                Row row = sh.getRow(r);
+                if (row == null) continue;
+                Cell q = row.getCell(16); // Q 鍒� = 绱
+                if (q == null || q.getCellType() != CellType.FORMULA) continue;
+                boolean hasMonthly = false;
+                for (int m = 1; m <= 7 && !hasMonthly; m++) {
+                    Cell v = row.getCell(2 + 2 * (m - 1)); // C,E,G,I,K,M,O
+                    if (v != null && v.getCellType() != CellType.BLANK) hasMonthly = true;
+                }
+                if (!hasMonthly) continue; // 鎺掗櫎椤甸/椤典腑璺ㄩ〉绛炬牎楠屽叕寮忚锛堟棤鏈堝害鍊硷級
+                int excelRow = r + 1; // 鍏紡鍐呭紩鐢ㄤ负 Excel 1-based 琛屽彿
+                for (int m = keepMonths + 1; m <= 7; m++) {
+                    int valueCol = 2 + 2 * (m - 1);     // 2026 褰撴湀鍊煎垪
+                    int yoyCol = valueCol + 1;          // 褰撴湀鍚屾瘮鍒�
+                    String vLetter = colLetter(valueCol);
+                    Cell vc = row.getCell(valueCol);
+                    if (vc != null) {
+                        vc.setBlank();
+                        touched++;
+                    }
+                    Cell yc = row.getCell(yoyCol);
+                    if (yc != null) {
+                        yc.setBlank();
+                        touched++;
+                    }
+                    String fq = q.getCellFormula();
+                    if (fq != null && fq.contains("+" + vLetter + excelRow)) {
+                        q.setCellFormula(fq.replace("+" + vLetter + excelRow, ""));
+                        touched++;
+                    }
+                    Cell rc = row.getCell(17); // R 鍒� = 绱鍚屾瘮
+                    if (rc != null && rc.getCellType() == CellType.FORMULA) {
+                        String fr = rc.getCellFormula();
+                        int lastCol = 19 + 2 * (m - 1); // 2025 鍚屾湀鍒� T..AF锛�0-based锛歍=19,AF=31锛�
+                        String lLetter = colLetter(lastCol);
+                        String txt = fr;
+                        if (txt != null && txt.contains("," + lLetter + excelRow)) {
+                            txt = txt.replace("," + lLetter + excelRow, "");
+                            touched++;
+                        }
+                        if (txt != null && txt.contains("+" + lLetter + excelRow)) {
+                            txt = txt.replace("+" + lLetter + excelRow, "");
+                            touched++;
+                        }
+                        if (txt != null && !txt.equals(fr)) rc.setCellFormula(txt);
+                    }
+                }
+            }
+        }
+        return touched;
+    }
+
     /** 姹囨�诲伐浣滅翱骞翠唤鍔ㄦ�佸寲锛氫粎鎶� 2026骞� 鍓嶇紑鏇挎崲涓虹洰鏍囧勾锛�2025/2024 鍙傝�冨垪涓嶅姩锛� */
     private void dynamicSummaryYear(XSSFWorkbook wb, int year) {
         String oldPrefix = "2026骞�";

--
Gitblit v1.9.1