python 生成復雜表格,自動分頁等功能

python 生成復雜表格,自動分頁等功能

解決將Python中的樹形目錄數據轉換為Word表格,并生成帶有合并單元格的檢測報告的問題。首先,要解決“tree目錄數據”和“Word表格互換”,指將樹形結構的數據轉換成Word表格,并在轉換過程中合并相應的單元格以反映層次結構。此外,還有自動分頁和固定表頭的問題,現在可能希望生成的報告能夠自動處理這些格式問題。

首先,我需要明確樹形目錄數據的結構。通常,樹形結構有父子節點關系,比如文件夾結構,每個節點可能有名稱、類型、大小、修改日期等屬性。希望將這些層次結構在Word表格中展示,通過合并單元格來表示父子關系,例如,一個父節點占據一行,其子節點在下方縮進顯示,可能需要合并某些列來體現層級。

在Python中,處理樹形結構通常使用遞歸。對于每個節點,可能需要確定其在表格中的行位置,并根據層級決定合并哪些單元格。例如,根節點可能需要合并所有列的一行,子節點可能只在第一列顯示名稱,后面的列合并或留空,或者根據具體需求調整。

生成Word文檔需要使用python-docx庫。該庫允許創建表格、設置樣式、合并單元格等操作。關鍵點是如何遍歷樹形數據并動態生成表格行,同時處理合并單元格的邏輯。可能需要為每個節點計算其在表格中的行數和列數,特別是當子節點存在時,父節點可能需要跨多行合并。

以下是試驗代碼

from docx import Document
from docx.shared import Pt, Cm
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.shared import OxmlElement, qn
import randomclass TreeNode:def __init__(self, name, depth=0, is_file=False, size=0, parent=None):self.name = nameself.depth = depthself.is_file = is_fileself.size = f"{size} KB" if is_file else ""self.parent = parentself.children = []self.start_row = 0self.end_row = 0self.col_span = 1  # 新增橫向合并跨度class EnhancedDirectoryReport:def __init__(self, filename):self.doc = Document()self.filename = filenameself._setup_document()self.table = Noneself.current_row = 0self.column_map = ['一級目錄', '二級目錄', '三級目錄', '文件名', '路徑', '大小']self.current_table = Noneself.current_page_rows = 0self.max_page_rows = 35  # 根據實際內容調整每頁行數self.active_directory = {}  # 記錄當前活躍的目錄層級def _setup_document(self):section = self.doc.sections[0]margins = {'left': 2, 'right': 2, 'top': 2.5, 'bottom': 2.5}for attr, cm_val in margins.items():setattr(section, f"{attr}_margin", Cm(cm_val))style = self.doc.styles['Normal']style.font.name = '微軟雅黑'style.font.size = Pt(10)def _create_new_page(self):"""創建新頁面并初始化表格"""if self.current_table is not None:self.doc.add_page_break()self.current_table = self.doc.add_table(rows=0, cols=6)self.current_table.style = 'Table Grid'widths = [Cm(3.5), Cm(3.5), Cm(3.5), Cm(4), Cm(6), Cm(2.5)]for idx, w in enumerate(widths):self.current_table.columns[idx].width = wself._create_table_header()print('建表頭后',self.current_row,self.current_page_rows)self.current_page_rows = 1  # 表頭占1行# 重新應用活躍目錄self._reapply_active_directory()def _reapply_active_directory(self):"""在新頁重新應用當前活躍目錄"""for depth in [1, 2, 3]:if depth in self.active_directory:node = self.active_directory[depth]self._add_directory_row(node, depth)def _add_directory_row(self, node, depth):"""添加目錄行并更新活躍狀態"""row = self.current_table.add_row()cells = row.cells# 填充目錄信息cells[depth - 1].text = node.namecells[depth - 1].paragraphs[0].alignment = WD_TABLE_ALIGNMENT.LEFT# 設置跨列合并if depth == 1:cells[0].merge(cells[5])elif depth == 2:cells[1].merge(cells[5])elif depth == 3:cells[2].merge(cells[5])# 更新活躍目錄self.active_directory[depth] = nodeself.current_page_rows += 1def _check_page_break(self):"""檢查是否需要分頁"""if self.current_page_rows >= self.max_page_rows:self._create_new_page()print('分頁')def _add_file_row(self, node):"""添加文件行"""self._check_page_break()row = self.current_table.add_row()cells = row.cells# 填充文件信息cells[3].text = node.namecells[4].text = self._get_full_path(node)cells[5].text = node.size# 繼承活躍目錄for depth in [1, 2, 3]:if depth in self.active_directory:cells[depth - 1].text = self.active_directory[depth].namecells[depth - 1].paragraphs[0].alignment = WD_TABLE_ALIGNMENT.CENTERself.current_page_rows += 1def _get_full_path(self, node):path = []current = node.parentwhile current and current.depth > 0:path.insert(0, current.name)current = current.parentreturn '/' + '/'.join(path)def process_structure(self, root):"""處理目錄結構"""self._create_new_page()stack = [(root, False)]  # (node, visited)while stack:node, visited = stack.pop()if visited:# 后序遍歷處理合并if not node.is_file:self._update_active_directory(node)continueif node.is_file:self._add_file_row(node)else:# 前序遍歷添加目錄self._check_page_break()self._add_directory_row(node, node.depth)stack.append((node, True))# 逆向添加子節點以保持順序for child in reversed(node.children):stack.append((child, False))self.doc.save(self.filename)def _update_active_directory(self, node):"""更新活躍目錄狀態"""# 清除子目錄狀態for depth in list(self.active_directory.keys()):if depth > node.depth:del self.active_directory[depth]def _create_table_header(self):header = self.table.add_row()for idx, text in enumerate(self.column_map):cell = header.cells[idx]cell.text = textcell.paragraphs[0].runs[0].font.bold = Truecell.paragraphs[0].alignment = WD_TABLE_ALIGNMENT.CENTERself._set_cell_color(cell, 'A3D3D3')tr = header._trtrPr = tr.get_or_add_trPr()tblHeader = OxmlElement('w:tblHeader')tblHeader.set(qn('w:val'), "true")trPr.append(tblHeader)print(self.current_row)self.current_row += 1def _set_cell_color(self, cell, hex_color):shading = OxmlElement('w:shd')shading.set(qn('w:fill'), hex_color)cell._tc.get_or_add_tcPr().append(shading)def _smart_merge(self, node):"""智能合并策略核心方法"""# 垂直合并處理if node.depth <= 3 and not node.is_file:self._vertical_merge(node)# 橫向合并處理if node.depth == 1 and not any(not c.is_file for c in node.children):self._horizontal_merge(node, 1, 3)  # 一級目錄合并到文件名列if node.depth == 2 and not any(not c.is_file for c in node.children):self._horizontal_merge(node, 2, 3)  # 二級目錄合并到文件名列def _horizontal_merge(self, node, start_col, end_col):"""安全橫向合并方法"""for row_idx in range(node.start_row, node.end_row):# 獲取需要合并的單元格print('nc ', row_idx, start_col, end_col)start_cell = self.table.cell(row_idx, start_col)end_cell = self.table.cell(row_idx, end_col)print(row_idx, start_col, end_col)print('開結',start_cell, end_cell)# 檢查是否已經被合并if start_cell._element is end_cell._element:print('已合并過')continueelse:start_cell.merge(end_cell)def _vertical_merge(self, node):"""垂直方向合并"""if node.start_row >= node.end_row:returndepth_col_map = {1: 0, 2: 1, 3: 2}col_idx = depth_col_map.get(node.depth)if col_idx is not None:try:start_cell = self.table.cell(node.start_row, col_idx)end_cell = self.table.cell(node.end_row - 1, col_idx)start_cell.merge(end_cell)start_cell.text = node.nameexcept IndexError as e:print(f"垂直合并失敗:{node.name}")raise edef _fill_row_data(self, node):"""填充數據并設置合并策略"""row = self.table.add_row()cells = row.cells# 文件信息if node.is_file:cells[3].text = node.namecells[4].text = self._get_full_path(node)cells[5].text = node.size# else:#     # 設置目錄層級#     for d in range(1, 4):#         print(d, cells[d])#         print(node.name, node.depth)#         if node.depth == d:#             cells[d - 1].text = node.name#             # if d < 3:#             #     cells[d].merge(cells[d])# 設置樣式for cell in cells:cell.vertical_alignment = WD_TABLE_ALIGNMENT.CENTERself.current_row += 1return row# def _get_full_path(self, node):#     path = []#     current = node.parent#     while current and current.depth > 0:#         path.insert(0, current.name)#         current = current.parent#     return '/' + '/'.join(path) + ('' if node.is_file else f'/{node.name}')def _process_node(self, node):node.start_row = self.current_row#增限制,如為凈空不加行if node.depth > 1 and node.is_file:self._fill_row_data(node)for child in node.children:self._process_node(child)node.end_row = self.current_rowself._smart_merge(node)def generate_report(self, root):self.table = self.doc.add_table(rows=0, cols=6)self.table.style = 'Table Grid'widths = [Cm(3.5), Cm(3.5), Cm(3.5), Cm(4), Cm(6), Cm(2.5)]for idx, w in enumerate(widths):self.table.columns[idx].width = w# self._create_table_header()self._create_new_page()self._process_node(root)print(self.doc.tables)self.doc.save(self.filename)# 測試數據生成器
class TestDataGenerator:@staticmethoddef create_large_structure():root = TreeNode("ROOT", depth=0)# 一級目錄(10個)for i in range(1, 11):dir1 = TreeNode(f"一級目錄_{i}", depth=1, parent=root)root.children.append(dir1)# 30%概率沒有子目錄if random.random() < 0.3:# 直接添加文件for j in range(random.randint(2, 5)):file = TreeNode(f"文件_{i}-{j}.docx", depth=4,is_file=True,size=random.randint(100, 5000),parent=dir1)dir1.children.append(file)continue# 二級目錄(每個一級目錄3-5個)for j in range(random.randint(3, 5)):dir2 = TreeNode(f"二級目錄_{i}-{j}", depth=2, parent=dir1)dir1.children.append(dir2)# 50%概率沒有三級目錄if random.random() < 0.5:# 直接添加文件for k in range(random.randint(3, 6)):file = TreeNode(f"文件_{i}-{j}-{k}.xlsx", depth=4,is_file=True,size=random.randint(100, 5000),parent=dir2)dir2.children.append(file)continue# 三級目錄(每個二級目錄2-4個)for k in range(random.randint(2, 4)):dir3 = TreeNode(f"三級目錄_{i}-{j}-{k}", depth=3, parent=dir2)dir2.children.append(dir3)# 添加文件for m in range(random.randint(3, 8)):file = TreeNode(f"文件_{i}-{j}-{k}-{m}.pptx", depth=4,is_file=True,size=random.randint(100, 5000),parent=dir3)dir3.children.append(file)return rootif __name__ == '__main__':# 生成測試數據data_generator = TestDataGenerator()root_node = data_generator.create_large_structure()# 生成報告report = EnhancedDirectoryReport("上下左右目錄2.docx")report.generate_report(root_node)

效果如圖所示:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82556.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82556.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82556.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

根據Cortex-M3(包括STM32F1)權威指南講解MCU內存架構與如何查看編譯器生成的地址具體位置

首先我們先查看官方對于Cortex-M3預定義的存儲器映射 1.存儲器映射 1.1 Cortex-M3架構的存儲器結構 內部私有外設總線&#xff1a;即AHB總線&#xff0c;包括NVIC中斷&#xff0c;ITM硬件調試&#xff0c;FPB, DWT。 外部私有外設總線&#xff1a;即APB總線&#xff0c;用于…

Linux中硬件信息查詢利器——lshw命令詳解!

lshw&#xff08;List Hardware&#xff09;是 Linux 系統下的一款命令行工具&#xff0c;用于全面檢測并顯示詳細的硬件信息。它能夠報告 CPU、內存、主板、存儲設備、顯卡、網絡設備等幾乎所有硬件組件的詳細信息&#xff0c;適用于系統管理、故障排查和硬件兼容性檢查等場景…

用llama3微調了一個WiFiGPT 用于室內定位

一段話總結 本文提出WiFiGPT,一種基于Decoder-Only Transformer(如LLaMA 3)的室內定位系統,通過將WiFi遙測數據(如CSI、FTM、RSSI)轉換為文本序列進行端到端訓練,無需手工特征工程即可實現高精度定位。實驗表明,WiFiGPT在LOS環境中實現亞米級精度(MAE低至0.90米),在…

大模型系列22-MCP

大模型系列22-MCP 玩轉 MCP 協議&#xff1a;用 Cline DeepSeek 接入天氣服務什么是 MCP&#xff1f;環境準備&#xff1a;VScode Cline DeepSeek**配置 DeepSeek 模型&#xff1a;****配置 MCP 工具****uvx是什么&#xff1f;****安裝 uv&#xff08;會自動有 uvx 命令&…

Go語言Map的底層原理

概念 map 又稱字典&#xff0c;是一種常用的數據結構&#xff0c;核心特征包含下述三點&#xff1a; &#xff08;1&#xff09;存儲基于 key-value 對映射的模式&#xff1b; &#xff08;2&#xff09;基于 key 維度實現存儲數據的去重&#xff1b; &#xff08;3&#x…

循環神經網絡(RNN):原理、架構與實戰

循環神經網絡&#xff08;Recurrent Neural Network, RNN&#xff09;是一類專門處理序列數據的神經網絡&#xff0c;如時間序列、自然語言、音頻等。與前饋神經網絡不同&#xff0c;RNN 引入了循環結構&#xff0c;能夠捕捉序列中的時序信息&#xff0c;使模型在不同時間步之間…

java 項目登錄請求業務解耦模塊全面

登錄是統一的閘機&#xff1b; 密碼存在數據庫中&#xff0c;用的是密文&#xff0c;后端加密&#xff0c;和數據庫中做對比 1、UserController public class UserController{Autowiredprivate IuserService userservicepublic JsonResult login(Validated RequestBody UserLo…

【手寫數據庫核心揭秘系列】第9節 可重入的SQL解析器,不斷解析Structure Query Language,語言翻譯好幫手

可重入的SQL解析器 文章目錄 可重入的SQL解析器一、概述 二、可重入解析器 2.1 可重入設置 2.2 記錄狀態的數據結構 2.3 節點數據類型定義 2.4 頭文件引用 三、調整后的程序結構 四、總結 一、概述 現在就來修改之前sqlscanner.l和sqlgram.y程序,可以不斷輸入SQL語句,循環執…

微軟開源bitnet b1.58大模型,應用效果測評(問答、知識、數學、邏輯、分析)

微軟開源bitnet b1.58大模型,應用效果測評(問答、知識、數學、邏輯、分析) 目 錄 1. 前言... 2 2. 應用部署... 2 3. 應用效果... 3 1.1 問答方面... 3 1.2 知識方面... 4 1.3 數字運算... 6 1.4 邏輯方面... …

用HTML5+JavaScript實現漢字轉拼音工具

用HTML5JavaScript實現漢字轉拼音工具 前一篇博文&#xff08;https://blog.csdn.net/cnds123/article/details/148067680&#xff09;提到&#xff0c;當需要將拼音添加到漢字上面時&#xff0c;用python實現比HTML5JavaScript實現繁瑣。在這篇博文中用HTML5JavaScript實現漢…

鴻蒙OSUniApp 開發的動態背景動畫組件#三方框架 #Uniapp

使用 UniApp 開發的動態背景動畫組件 前言 在移動應用開發中&#xff0c;動態背景動畫不僅能提升界面美感&#xff0c;還能增強用戶的沉浸感和品牌辨識度。無論是登錄頁、首頁還是活動頁&#xff0c;恰到好處的動態背景都能讓產品脫穎而出。隨著鴻蒙&#xff08;HarmonyOS&am…

云原生技術架構技術探索

文章目錄 前言一、什么是云原生技術架構二、云原生技術架構的優勢三、云原生技術架構的應用場景結語 前言 在當今的技術領域&#xff0c;云原生技術架構正以一種勢不可擋的姿態席卷而來&#xff0c;成為了眾多開發者、企業和技術愛好者關注的焦點。那么&#xff0c;究竟什么是…

AWS之AI服務

目錄 一、AWS AI布局 ??1. 底層基礎設施與芯片?? ??2. AI訓練框架與平臺?? ??3. 大模型與應用層?? ??4. 超級計算與網絡?? ??與競品對比?? AI服務 ??1. 機器學習平臺?? ??2. 預訓練AI服務?? ??3. 邊緣與物聯網AI?? ??4. 數據與AI…

lwip_bind、lwip_listen 是阻塞函數嗎

在 lwIP 協議棧中&#xff0c;lwip_bind 和 lwip_listen 函數本質上是非阻塞的。 通常&#xff0c;bind和listen在大多數實現中都是非阻塞的&#xff0c;因為它們只是設置套接字的屬性&#xff0c;不需要等待外部事件。阻塞通常發生在接受連接&#xff08;accept&#xff09;、…

【后端高階面經:消息隊列篇】28、從零設計高可用消息隊列

一、消息隊列架構設計的核心目標與挑戰 設計高性能、高可靠的消息隊列需平衡功能性與非功能性需求,解決分布式系統中的典型問題。 1.1 核心設計目標 吞吐量:支持百萬級消息/秒處理,通過分區并行化實現橫向擴展。延遲:端到端延遲控制在毫秒級,適用于實時業務場景。可靠性…

【運維實戰】Linux 內存調優之進程內存深度監控

寫在前面 內容涉及 Linux 進程內存監控 監控方式包括傳統工具 ps/top/pmap ,以及 cgroup 內存子系統&#xff0c;proc 內存偽文件系統 監控內容包括進程內存使用情況&#xff0c; 內存全局數據統計&#xff0c;內存事件指標&#xff0c;以及進程內存段數據監控 監控進程的內…

決策樹 GBDT XGBoost LightGBM

一、決策樹 1. 決策樹有一個很強的假設&#xff1a; 信息是可分的&#xff0c;否則無法進行特征分支 2. 決策樹的種類&#xff1a; 2. ID3決策樹&#xff1a; ID3決策樹的數劃分標準是信息增益&#xff1a; 信息增益衡量的是通過某個特征進行數據劃分前后熵的變化量。但是&…

java基礎學習(十四)

文章目錄 4-1 面向過程與面向對象4-2 Java語言的基本元素&#xff1a;類和對象面向對象的思想概述 4-3 對象的創建和使用內存解析匿名對象 4-1 面向過程與面向對象 面向過程(POP) 與 面向對象(OOP) 二者都是一種思想&#xff0c;面向對象是相對于面向過程而言的。面向過程&…

TCP 三次握手,第三次握手報文丟失會發生什么?

文章目錄 RTO(Retransmission Timeout)注意 客戶端收到服務端的 SYNACK 報文后&#xff0c;會回給服務端一個 ACK 報文&#xff0c;之后處于 ESTABLISHED 狀態 因為第三次握手的 ACK 是對第二次握手中 SYN 的確認報文&#xff0c;如果第三次握手報文丟失了&#xff0c;服務端就…

deepseek告訴您http與https有何區別?

有用戶經常問什么是Http , 什么是Https &#xff1f; 兩者有什么區別&#xff0c;下面為大家介紹一下兩者的區別 一、什么是HTTP HTTP是一種無狀態的應用層協議&#xff0c;用于在客戶端瀏覽器和服務器之間傳輸網頁信息&#xff0c;默認使用80端口 二、HTTP協議的特點 HTTP協議…