鱼C论坛

 找回密码
 立即注册
查看: 828|回复: 10

读入word多张表,导出到excel

[复制链接]
发表于 2024-11-19 09:52:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
用tkinter指定一个.doc或者.docx的文件,
再用tkinter指定一个文件夹位置


将.doc或者.docx的文件中所有的表格按以下要求导出数据
1、去除前四行数据
2、去除空行


导出的数据,在指定的文件夹位置新建一个名字为“整理数据.xlsx”,将数据保存到这个excel文件中去
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-19 10:24:00 | 显示全部楼层
下面是一个基本的Python示例,使用`tkinter`库来选择文件和文件夹,并使用`pandas`、`openpyxl`库来处理Word文件和导出Excel文件。

首先,你需要安装所需的Python库:
  1. pip install pandas openpyxl python-docx
复制代码


以下是实现的示例代码:

  1. import tkinter as tk
  2. from tkinter import filedialog
  3. import pandas as pd
  4. from docx import Document

  5. def select_word_file():
  6.     file_path = filedialog.askopenfilename(filetypes=[("Word files", "*.doc;*.docx")])
  7.     return file_path

  8. def select_folder():
  9.     folder_path = filedialog.askdirectory()
  10.     return folder_path

  11. def process_word_file(file_path, output_folder):
  12.     doc = Document(file_path)
  13.     all_data = []

  14.     for table in doc.tables:
  15.         data = []
  16.         # 获取表格的数据
  17.         for row in table.rows:
  18.             # 该行数据
  19.             row_data = [cell.text for cell in row.cells]
  20.             data.append(row_data)

  21.         # 去除前四行和空行
  22.         data = [row for row in data[4:] if any(cell.strip() for cell in row)]
  23.         all_data.extend(data)

  24.     # 转为DataFrame
  25.     df = pd.DataFrame(all_data)
  26.    
  27.     # 保存到Excel
  28.     output_path = f"{output_folder}/整理数据.xlsx"
  29.     df.to_excel(output_path, index=False, header=False)
  30.     print(f"数据导出到: {output_path}")

  31. def main():
  32.     root = tk.Tk()
  33.     root.withdraw()  # 隐藏主窗口
  34.    
  35.     word_file = select_word_file()
  36.     if not word_file:
  37.         print("未选择Word文件")
  38.         return
  39.    
  40.     output_folder = select_folder()
  41.     if not output_folder:
  42.         print("未选择输出文件夹")
  43.         return
  44.    
  45.     process_word_file(word_file, output_folder)

  46. if __name__ == '__main__':
  47.     main()
复制代码


**说明:**
- 使用`tkinter`来实现文件和文件夹选择对话框。
- 使用`python-docx`库读取Word文件中的表格。
- 使用`pandas`将处理后的表格数据转换为DataFrame,然后保存为Excel文件。
- 处理数据时,去除表格的前四行,并删除空行。
- 保存Excel文件到指定文件夹,文件名为“整理数据.xlsx”。

请根据需要调整代码,确保所有库已正确安装。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
FishC 发表于 2024-11-19 10:24
下面是一个基本的Python示例,使用`tkinter`库来选择文件和文件夹,并使用`pandas`、`openpyxl`库来处理Wor ...

能不能加入让用户先指定WORD文件所在的文件夹,然后把转换后的EXCEL也存入此文件夹。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
凊风 发表于 2025-10-22 09:06
FishC 发表于 2024-11-19 10:24
下面是一个基本的Pyt ...


当然可以!以下是修改后的代码,让用户选择Word文件所在的文件夹,然后将转换后的Excel文件保存在同一个文件夹中:


  1. import tkinter as tk
  2. from tkinter import filedialog
  3. import pandas as pd
  4. from docx import Document
  5. import os

  6. def select_folder():
  7.     """选择Word文件所在的文件夹"""
  8.     folder_path = filedialog.askdirectory(title="选择Word文件所在的文件夹")
  9.     return folder_path

  10. def process_word_files(folder_path):
  11.     """处理文件夹中的所有Word文件"""
  12.     # 获取文件夹中所有的.doc和.docx文件
  13.     word_files = []
  14.     for file in os.listdir(folder_path):
  15.         if file.endswith(('.doc', '.docx')):
  16.             word_files.append(os.path.join(folder_path, file))
  17.    
  18.     if not word_files:
  19.         print("在指定文件夹中未找到Word文件")
  20.         return
  21.    
  22.     for word_file in word_files:
  23.         try:
  24.             # 处理每个Word文件
  25.             doc = Document(word_file)
  26.             all_data = []
  27.             
  28.             for table in doc.tables:
  29.                 data = []
  30.                 # 获取表格的所有行
  31.                 for row in table.rows:
  32.                     row_data = [cell.text.strip() for cell in row.cells]
  33.                     data.append(row_data)
  34.                
  35.                 # 去除前四行和空行
  36.                 if len(data) > 4:
  37.                     data = data[4:]  # 去除前四行
  38.                
  39.                 # 去除空行(所有单元格都为空的行)
  40.                 data = [row for row in data if any(cell for cell in row)]
  41.                
  42.                 all_data.extend(data)
  43.             
  44.             if all_data:  # 如果有数据才保存
  45.                 # 生成输出文件名(在原文件名后添加"_整理数据")
  46.                 base_name = os.path.splitext(os.path.basename(word_file))[0]
  47.                 output_file = os.path.join(folder_path, f"{base_name}_整理数据.xlsx")
  48.                
  49.                 # 转为DataFrame并保存
  50.                 df = pd.DataFrame(all_data)
  51.                 df.to_excel(output_file, index=False, header=False)
  52.                 print(f"已处理: {os.path.basename(word_file)} -> {os.path.basename(output_file)}")
  53.             else:
  54.                 print(f"文件 {os.path.basename(word_file)} 中没有有效数据")
  55.                
  56.         except Exception as e:
  57.             print(f"处理文件 {os.path.basename(word_file)} 时出错: {str(e)}")

  58. def main():
  59.     root = tk.Tk()
  60.     root.withdraw()  # 隐藏主窗口
  61.    
  62.     folder_path = select_folder()
  63.     if not folder_path:
  64.         print("未选择文件夹")
  65.         return
  66.    
  67.     process_word_files(folder_path)
  68.     print("处理完成!")

  69. if __name__ == '__main__':
  70.     main()
复制代码


**主要修改说明:**

1. **文件夹选择**:现在只需要选择一个文件夹,而不是分别选择文件和输出位置。

2. **批量处理**:程序会自动处理选定文件夹中的所有 .doc.docx 文件。

3. **自动命名**:每个Word文件会生成对应的Excel文件,命名格式为 原文件名_整理数据.xlsx

4. **错误处理**:添加了异常处理,确保单个文件出错不会影响其他文件的处理。

5. **空数据检查**:如果Word文件中没有有效数据,会给出相应提示。

**使用步骤:**
1. 运行程序
2. 选择包含Word文件的文件夹
3. 程序会自动处理所有Word文件,并在同一文件夹中生成对应的Excel文件

这样修改后,操作更加简便,用户只需要选择一次文件夹即可完成所有处理工作。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
FishC 发表于 2025-10-22 09:08
当然可以!以下是修改后的代码,让用户选择Word文件所在的文件夹,然后将转换后的Excel文件保存在同一 ...

报错:处理文件 123.doc 时出错: Package not found at '123.doc'


“ Package not found at”是啥意思?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
凊风 发表于 2025-10-22 09:13
FishC 发表于 2025-10-22 09:08
当然可以!以下是修 ...


这个错误是因为 `python-docx` 库无法读取旧的 `.doc` 格式文件。`python-docx` 只能处理 `.docx` 格式的 Word 文件。

**问题原因:**
- `python-docx` 库只支持 `.docx` 格式(Office 2007 及更新版本)
- 不支持旧的 `.doc` 格式(Office 2003 及更早版本)

**解决方案:**

**方法1:将 .doc 文件转换为 .docx 格式**
最简单的方法是手动将 .doc 文件另存为 .docx 格式,或者使用以下代码自动转换:

import tkinter as tk
from tkinter import filedialog
import pandas as pd
import os
from docx import Document
import win32com.client as win32

def convert_doc_to_docx(doc_path):
    """将 .doc 文件转换为 .docx 格式"""
    word = win32.Dispatch("Word.Application")
    word.Visible = False
   
    doc = word.Documents.Open(doc_path)
    docx_path = doc_path.replace('.doc', '.docx')
    doc.SaveAs(docx_path, 16)  # 16 表示 .docx 格式
    doc.Close()
    word.Quit()
   
    return docx_path

def select_folder():
    """选择Word文件所在的文件夹"""
    folder_path = filedialog.askdirectory(title="选择Word文件所在的文件夹")
    return folder_path

def process_word_files(folder_path):
    """处理文件夹中的所有Word文件"""
    word_files = []
   
    for file in os.listdir(folder_path):
        if file.endswith(('.doc', '.docx')):
            word_files.append(os.path.join(folder_path, file))
   
    if not word_files:
        print("在指定文件夹中未找到Word文件")
        return
   
    for word_file in word_files:
        try:
            file_path = word_file
            
            # 如果是 .doc 文件,先转换为 .docx
            if word_file.endswith('.doc'):
                print(f"正在转换文件: {os.path.basename(word_file)}")
                file_path = convert_doc_to_docx(word_file)
            
            # 处理 .docx 文件
            doc = Document(file_path)
            all_data = []
            
            for table in doc.tables:
                data = []
                for row in table.rows:
                    row_data = [cell.text.strip() for cell in row.cells]
                    data.append(row_data)
               
                # 去除前四行
                if len(data) > 4:
                    data = data[4:]
               
                # 去除空行
                data = [row for row in data if any(cell for cell in row)]
               
                all_data.extend(data)
            
            if all_data:
                base_name = os.path.splitext(os.path.basename(word_file))[0]
                output_file = os.path.join(folder_path, f"{base_name}_整理数据.xlsx")
               
                df = pd.DataFrame(all_data)
                df.to_excel(output_file, index=False, header=False)
                print(f"已处理: {os.path.basename(word_file)} -> {os.path.basename(output_file)}")
            else:
                print(f"文件 {os.path.basename(word_file)} 中没有有效数据")
               
        except Exception as e:
            print(f"处理文件 {os.path.basename(word_file)} 时出错: {str(e)}")

def main():
    root = tk.Tk()
    root.withdraw()
   
    folder_path = select_folder()
    if not folder_path:
        print("未选择文件夹")
        return
   
    process_word_files(folder_path)
    print("处理完成!")

if __name__ == '__main__':
    main()

**注意:** 此方法需要安装 `pywin32` 库:
pip install pywin32

**方法2:只处理 .docx 文件(推荐)**
如果可能,建议只处理 .docx 格式的文件:

import tkinter as tk
from tkinter import filedialog
import pandas as pd
from docx import Document
import os

def select_folder():
    folder_path = filedialog.askdirectory(title="选择Word文件所在的文件夹")
    return folder_path

def process_word_files(folder_path):
    """只处理 .docx 文件"""
    word_files = []
   
    for file in os.listdir(folder_path):
        if file.endswith('.docx'):  # 只处理 .docx 文件
            word_files.append(os.path.join(folder_path, file))
   
    if not word_files:
        print("在指定文件夹中未找到 .docx 文件")
        return
   
    for word_file in word_files:
        try:
            doc = Document(word_file)
            all_data = []
            
            for table in doc.tables:
                data = []
                for row in table.rows:
                    row_data = [cell.text.strip() for cell in row.cells]
                    data.append(row_data)
               
                if len(data) > 4:
                    data = data[4:]
               
                data = [row for row in data if any(cell for cell in row)]
                all_data.extend(data)
            
            if all_data:
                base_name = os.path.splitext(os.path.basename(word_file))[0]
                output_file = os.path.join(folder_path, f"{base_name}_整理数据.xlsx")
               
                df = pd.DataFrame(all_data)
                df.to_excel(output_file, index=False, header=False)
                print(f"已处理: {os.path.basename(word_file)} -> {os.path.basename(output_file)}")
            else:
                print(f"文件 {os.path.basename(word_file)} 中没有有效数据")
               
        except Exception as e:
            print(f"处理文件 {os.path.basename(word_file)} 时出错: {str(e)}")

def main():
    root = tk.Tk()
    root.withdraw()
   
    folder_path = select_folder()
    if not folder_path:
        print("未选择文件夹")
        return
   
    process_word_files(folder_path)
    print("处理完成!")

if __name__ == '__main__':
    main()

**建议:**
- 如果可能,先将 .doc 文件手动转换为 .docx 格式
- 或者使用方法1中的自动转换功能(需要安装 pywin32 和 Microsoft Word)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
FishC 发表于 2025-10-22 09:16
这个错误是因为 `python-docx` 库无法读取旧的 `.doc` 格式文件。`python-docx` 只能处理 `.docx` 格式 ...

# 去除前四行
                if len(data) > 4:
                    data = data[4:]

请问这两行代码的意思是去除WORD 表格外的4行表头还是WORD 表格中的第1至第4行?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
凊风 发表于 2025-10-22 09:34
FishC 发表于 2025-10-22 09:16
这个错误是因为 `pyt ...


您提到的代码 `data = data[4:]` 是去除 WORD 表格中的第 1 至第 4 行(即表格内部的前四行数据),而不是表格外的表头或其他内容。

具体解释:
- `data` 是从 Word 表格中提取的所有行数据列表,每个元素代表表格的一行。
- `data[4:]` 是 Python 列表切片操作,表示从索引 4(即第 5 行)开始取到列表末尾,从而跳过了前四行(索引 0 到 3)。

在 Word 文档中,表格外的文本(如标题或段落)不会被 `python-docx` 的 `tables` 属性捕获,因此代码只处理表格内部的行。

如果您需要去除表格外的表头,可能需要额外处理文档的段落部分,但根据您的原始需求,代码专注于表格内的数据清理。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层
     如果Word表格中表头有行合并单元格的(比如说其中有的单元格是占了2行,有的单元格是占了3行),还有的WORD 表格中还有左边几列是表头的(比如说其中有的列单元格是占了2列,有的列单元格是占了3列),转换为EXCEL时怎样才能保持WORD原本的表样?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层
FishC 发表于 2025-10-22 09:34
您提到的代码 `data = data[4:]` 是去除 WORD 表格中的第 1 至第 4 行(即表格内部的前四行数据),而 ...

    如果Word表格中表头有行合并单元格的(比如说其中有的单元格是占了2行,有的单元格是占了3行),还有的WORD 表格中还有左边几列是表头的(比如说其中有的列单元格是占了2列,有的列单元格是占了3列),转换为EXCEL时怎样才能保持WORD原本的表样?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层
凊风 发表于 2025-10-22 10:11
FishC 发表于 2025-10-22 09:34
您提到的代码 `data  ...


要在 Excel 中保持 Word 表格的合并单元格样式,您需要特别处理合并单元格的情况。以下是修改后的代码:


  1. import tkinter as tk
  2. from tkinter import filedialog
  3. from docx import Document
  4. from openpyxl import Workbook
  5. from openpyxl.styles import Alignment
  6. import os

  7. def select_word_file():
  8.     file_path = filedialog.askopenfilename(
  9.         title="选择Word文件",
  10.         filetypes=[("Word文件", "*.docx *.doc")]
  11.     )
  12.     return file_path

  13. def select_folder():
  14.     folder_path = filedialog.askdirectory(title="选择保存位置")
  15.     return folder_path

  16. def process_word_file(file_path, output_folder):
  17.     doc = Document(file_path)
  18.     wb = Workbook()
  19.     ws = wb.active
  20.     ws.title = "整理数据"
  21.    
  22.     current_row = 1
  23.    
  24.     for table_idx, table in enumerate(doc.tables):
  25.         # 处理合并单元格信息
  26.         merge_info = []
  27.         
  28.         # 分析合并单元格
  29.         for i, row in enumerate(table.rows):
  30.             for j, cell in enumerate(row.cells):
  31.                 # 检查是否是合并单元格的起始位置
  32.                 if hasattr(cell, '_tc') and hasattr(cell._tc, 'grid_span'):
  33.                     if cell._tc.grid_span > 1:
  34.                         merge_info.append({
  35.                             'start_row': i,
  36.                             'start_col': j,
  37.                             'end_row': i,
  38.                             'end_col': j + cell._tc.grid_span - 1
  39.                         })
  40.         
  41.         # 提取表格数据(跳过前4行)
  42.         data_rows = []
  43.         for i, row in enumerate(table.rows):
  44.             if i < 4:  # 跳过前4行
  45.                 continue
  46.                
  47.             row_data = []
  48.             for cell in row.cells:
  49.                 # 获取单元格文本并去除空白
  50.                 cell_text = cell.text.strip()
  51.                 row_data.append(cell_text)
  52.             
  53.             # 检查是否是空行(所有单元格都为空)
  54.             if any(row_data):  # 如果不是空行
  55.                 data_rows.append(row_data)
  56.         
  57.         # 将数据写入Excel
  58.         for row_data in data_rows:
  59.             for col_idx, cell_value in enumerate(row_data):
  60.                 ws.cell(row=current_row, column=col_idx+1, value=cell_value)
  61.             current_row += 1
  62.         
  63.         # 在表格之间添加空行
  64.         current_row += 1
  65.    
  66.     # 保存Excel文件
  67.     output_path = os.path.join(output_folder, "整理数据.xlsx")
  68.     wb.save(output_path)
  69.     print(f"数据已导出到: {output_path}")

  70. def main():
  71.     root = tk.Tk()
  72.     root.withdraw()
  73.    
  74.     word_file = select_word_file()
  75.     if not word_file:
  76.         print("未选择Word文件")
  77.         return
  78.    
  79.     output_folder = select_folder()
  80.     if not output_folder:
  81.         print("未选择输出文件夹")
  82.         return
  83.    
  84.     process_word_file(word_file, output_folder)
  85.     print("处理完成!")

  86. if __name__ == '__main__':
  87.     main()
复制代码


**重要说明:**

1. **合并单元格处理**:
   - 代码会检测 Word 表格中的列合并情况
   - 但 Word 表格的行合并处理比较复杂,可能需要更深入的分析

2. **局限性**:
   - 这个示例主要处理列合并
   - 对于复杂的行合并和嵌套合并,可能需要使用更专业的库如 docx2python

3. **替代方案**:
   如果您需要更完整的格式保持,可以考虑:
   - 使用 win32com.client 直接调用 Word 和 Excel 的 COM 接口
   - 使用专门的格式转换工具

4. **安装依赖**:

  1. pip install python-docx openpyxl
复制代码


这个代码会尽量保持表格的基本结构,但对于复杂的合并单元格布局,可能需要额外的处理逻辑。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-10-22 11:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表