• 自己动手做一个批量doc转换为docx文件的小工具


    前言

    最近遇到了一个需求,就是要把大量的doc格式文件转换为docx文件,因此就动手做了一个批量转换的小工具。

    背景

    doc文件是什么?

    "doc" 文件是一种常见的文件格式,通常用于存储文本文档。它是 Microsoft Word 文档的文件扩展名。"doc" 是 "document" 的缩写,表示这是一个文档文件。这种文件格式通常包含文本、图像、表格、图形等内容,可以使用 Microsoft Word 或其他兼容的文字处理软件进行打开和编辑。

    docx文件是什么?

    "docx" 文件是 Microsoft Word 2007 及更高版本中使用的文档文件格式的扩展名。它是 Office Open XML (OOXML) 标准的一部分,是一种基于 XML 的开放标准格式,用于存储文本文档、图像、表格、图形等内容。与早期的 ".doc" 格式相比,".docx" 格式具有更高的兼容性和可扩展性,并且文件大小通常更小。由于其开放的特性,许多其他文字处理软件也支持 ".docx" 格式。

    为什么要将doc文件转化为docx文件?

    将 ".doc" 文件转换为 ".docx" 文件的主要原因包括:

    1. 更先进的格式:".docx" 使用 Office Open XML 格式,这是一种更现代、更有效的文件格式。它采用了基于 XML 的结构,使得文件更容易解析和处理,同时也提供了更好的兼容性和可扩展性。
    2. 减小文件大小:由于 ".docx" 文件采用了更高效的压缩技术和文件结构,相比 ".doc" 文件通常会更小,这对于存储和传输文件是有利的。
    3. 兼容性:许多最新版本的文字处理软件更支持 ".docx" 格式,而较旧的 ".doc" 格式可能会在一些软件中出现兼容性问题。将文件转换为 ".docx" 格式可以确保在不同平台和软件中的良好兼容性。
    4. 格式稳定性:".docx" 格式的结构更加稳定,不容易出现文件损坏或格式错误的问题,从而提高了文档的可靠性。

    综上所述,将 ".doc" 文件转换为 ".docx" 文件可以提高文件的效率、兼容性和稳定性,是一种值得推荐的做法。

    实践

    方案使用C#通过Microsoft Office Interop实现将.doc文件转换为.docx文件。

    添加引用:

    image-20240313204705350

    前提是需要电脑上安装有word。

    页面设计如下所示:

    image-20240319211338214

    选择doc文件所在的文件夹:

       // 创建一个新的FolderBrowserDialog
       FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
    
       // 设置FolderBrowserDialog的属性
       folderBrowserDialog.Description = "请选择待转换的doc文件所在的文件夹";
    
       // 显示FolderBrowserDialog,并获取结果
       if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
       {          
           docFolderPath = folderBrowserDialog.SelectedPath;
           richTextBox1.Text += $"你选择的待转换的doc文件所在的文件夹是:{docFolderPath}\r\n";
       }
    

    选择保存docx文件的文件夹:

     // 创建一个新的FolderBrowserDialog
     FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
    
     // 设置FolderBrowserDialog的属性
     folderBrowserDialog.Description = "请选择保存docx文件的文件夹";
    
     // 显示FolderBrowserDialog,并获取结果
     if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
     {
         // 用户已选择一个文件夹,可以通过folderBrowserDialog.SelectedPath获取所选文件夹的路径
         docxFolderPath = folderBrowserDialog.SelectedPath;
         richTextBox1.Text += $"你选择的保存docx文件的文件夹是:{docFolderPath}\r\n";
     }
    

    开始转换按钮事件处理函数:

     if (docFolderPath == null || docxFolderPath == null)
     {
         MessageBox.Show("请先选择doc文件所在的文件夹与保存docx文件的文件夹");
     }
     else
     {
    
         await DocToDocx();
     }
    

    为了避免阻塞界面,使用了异步方法。

    DocToDocx方法如下所示:

      public async System.Threading.Tasks.Task DocToDocx()
      {
          // 使用Task.Run来启动一个新的异步任务
          await System.Threading.Tasks.Task.Run(() =>
          {
              // 创建 Word 应用程序实例
              Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
           
              int i = 1;             
              // 遍历所有.doc文件
              foreach (string docFile in GetFiles(docFolderPath, "*.doc"))
              {
                  // 打开输入的 .doc 文件
                  Document doc = wordApp.Documents.Open(docFile);
    
                  // 获取不带扩展名的文件名
                  string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(docFile);
    
                  // 将扩展名改为.docx
                  string docxFileName = Path.ChangeExtension(fileNameWithoutExtension, ".docx");
    
                  string docxFilePath = Path.Combine(docxFolderPath, docxFileName);
    
                  // 将 .doc 文件保存为 .docx 格式
                  doc.SaveAs2(docxFilePath, WdSaveFormat.wdFormatXMLDocument);
    
                  // 关闭 .doc 文件
                  doc.Close();
    
                  // 释放 Document 对象的资源
                  System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
    
                  // 使用Invoke方法来更新richTextBox1
                  richTextBox1.Invoke((Action)(() =>
                  {
                      richTextBox1.Text += $"第{i}个文件:{docFile}转换完成 {DateTime.Now}\r\n";
    
                      // 设置插入点到文本的最后
                      richTextBox1.SelectionStart = richTextBox1.Text.Length;
    
                      // 滚动到插入点
                      richTextBox1.ScrollToCaret();
                  }));
    
                  i++;
              }
    
              // 退出 Word 应用程序
              wordApp.Quit();
    
              // 释放资源
              System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp);
         
              // 使用Invoke方法来更新richTextBox1
              richTextBox1.Invoke((Action)(() =>
              {
                  richTextBox1.Text += $"转换完成 {DateTime.Now}\r\n";
              }));
          });         
    

    GetFiles方法如下所示:

       // 这个方法返回一个IEnumerable,表示文件的路径
      public IEnumerable<string> GetFiles(string path, string searchPattern)
      {
          // 获取文件夹下的所有文件
          string[] files = Directory.GetFiles(path, searchPattern);
    
          // 遍历所有文件
          foreach (string file in files)
          {
              // 返回当前文件
              yield return file;
          }
      }
    

    这里使用了yield关键字,使用yield的好处如下:

    1. 延迟执行:迭代器的执行会被延迟,直到迭代器被消费时才开始。这意味着如果你有一个大的数据集合需要处理,但并不需要立即处理所有数据,那么使用yield可以帮助你节省内存和计算资源。
    2. 简化代码:yield可以使你的代码更简洁,更易于阅读和理解。你不需要创建一个临时的集合来存储你的结果,而是可以直接使用yield return来返回结果。
    3. 无需一次性生成所有结果:当处理大量数据时,一次性生成所有结果可能会消耗大量内存。使用yield可以在每次迭代时只生成一个结果,从而节省内存。

    实现原理其实很简单,就是用新版本的word打开再保存就行了。

     // 打开输入的 .doc 文件
     Document doc = wordApp.Documents.Open(docFile);
    
     // 获取不带扩展名的文件名
     string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(docFile);
    
     // 将扩展名改为.docx
     string docxFileName = Path.ChangeExtension(fileNameWithoutExtension, ".docx");
    
     string docxFilePath = Path.Combine(docxFolderPath, docxFileName);
    
     // 将 .doc 文件保存为 .docx 格式
     doc.SaveAs2(docxFilePath, WdSaveFormat.wdFormatXMLDocument);
    
     // 关闭 .doc 文件
     doc.Close();
    
     // 释放 Document 对象的资源
     System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
    

    需要转换的doc文件所在的文件夹:

    image-20240320160856832

    软件使用截图:

    image-20240320163426589

    实现效果:

    image-20240320163450275

    实现了批量doc文件转换为docx文件。

    如果不熟悉C#也可以通过Python实现。

    以下是一个文件转换的示例代码,经过测试可行:

    import os
    import win32com.client
    
    def convert_doc_to_docx(doc_path):
        # 创建Word应用程序对象
        word = win32com.client.Dispatch("Word.Application")
    
        # 打开.doc文件
        doc = word.Documents.Open(doc_path)
    
        # 设置新的文件路径
        docx_path = os.path.splitext(doc_path)[0] + ".docx"
    
        # 保存文件为.docx格式
        doc.SaveAs(docx_path, FileFormat=16)  # 16 represents wdFormatXMLDocument
    
        # 关闭文档
        doc.Close()
    
        # 关闭Word应用程序
        word.Quit()
    
    # 使用函数
    convert_doc_to_docx("Path")
    

    由于时间精力有限,没有写成批量处理的形式。

    还有一种方案就是在word里写VBA。

    采用哪种方案可以根据自己的熟练度。

  • 相关阅读:
    MySQL(1) 索引结构
    mybatis-plus使用generator快速生成代码,并手动添加数据库命令
    网站搜索引擎优化SEO面试题库和答案(SEO 主管、网站管理员、网站优化师、数字营销专家等)
    MySQL高级语句(一)
    微服务架构|go-zero 的自适应熔断器
    数据化运营09 抓住问题关键:用相关性分析拆解多个影响因素
    C++内存管理(2)new、delete详解
    【PyTorch】3-基础实战(ResNet)
    SpringSecurity系列——安全Http响应头day8-2(源于官网5.7.2版本)
    组函数会忽略null值
  • 原文地址:https://www.cnblogs.com/mingupupu/p/18085637