vba - 将Word文档拆分为单独文件的最快方法
问题描述
我正在寻找将一个大文件拆分为小文件的最有效方法。每个小文件都是大文件中的一段。如果大文件有大约 100 段,这不是问题,但如果超过 12k,则需要很长时间。
现在我为每个段落设置书签,接下来我在新文件中插入每个书签(我设置书签是因为有时我必须插入多个段落,但现在我不想让例子复杂化,所以我我用段落描述我的问题)。
这是我的代码(这是一个没有额外逻辑和错误处理的简单示例)。创建新文件,保存和关闭花费的时间最多。
Private Sub InsertBookmarks()
Dim p As Paragraph
Dim counter As Long
For Each p In ActiveDocument.Paragraphs
counter = counter + 1
ActiveDocument.Bookmarks.Add "File" & Format(counter, "00000#"), p.Range
Next p
ActiveDocument.Save
Set p = Nothing
End Sub
Private Sub SplitToSeparateFiles()
Dim path As String
Dim doc As Document
Dim b As Bookmark
path = ActiveDocument.path & "\"
WordBasic.DisableAutoMacros
For Each b In ActiveDocument.Bookmarks
Set doc = Documents.Add(Visible:=False)
doc.Range.FormattedText = b.Range
doc.SaveAs2 FileName:=path & b.Name
doc.Close wdDoNotSaveChanges
Next b
Set b = Nothing
Set doc = Nothing
End Sub
我考虑更改我的代码以在幕后使用 WordOpenXml 处理拆分,但我没有找到任何解决方案。如果有人对 .net 环境有任何想法,我可以使用 VSTO 插件。
任何想法更有效的方式?
解决方案
这是我使用的 C# 程序的摘录,该程序使用 FreeSpire.Doc nuget 包来读取 Word 文档。我知道您的问题是 VBA,但您最后提到了 .NET,所以我认为您并不反对在 C# 或 VB 中创建一些东西(vsual studio 应该免费供小时间使用)
using (Document document = new Document())
{
document.LoadFromFileInReadMode(@"C:\temp\word.docx", FileFormat.Docx);
foreach (Section s in document.Sections)
{
int pCount = 0;
foreach (Paragraph p in s.Paragraphs)
{
File.WriteAllText(@"c:\temp\p"+pCount+".txt", p.Text);
pCount++;
}
}
}
我不认为写 12,000 个文件需要几个小时,但我没有一个包含 12,000 个段落的 word 文档来测试它;让我知道你的结果?
编辑:
以下程序在配备 SSD 的 Core i7 上在 41 秒内创建了 12000 个文件:
using System;
using System.IO;
namespace ConsoleApp4
{
class Program
{
static void Main()
{
for(int i = 0; i < 12000; i++){
File.WriteAllText(@"c:\temp\x\" + i + ".txt", Guid.NewGuid().ToString());
}
}
}
}
使用它作为基准并假设加载大量文档可能需要一分钟,我希望进行拆分的 .NET 应用程序在包含数万段的 word doc 上花费几分钟
编辑2:
创建word文件。真正的过程可能是这样的,如果您从源中读取每个段落并使用同一段落制作一个新文档(尝试将旧段落分配给新文档):
using (Document document = new Document())
{
document.LoadFromFileInReadMode(@"C:\temp\word.docx", FileFormat.Docx);
foreach (Section s in document.Sections)
{
int pCount = 0;
foreach (Paragraph p in s.Paragraphs)
{
Document document = new Document();
Section s = document.AddSection();
s.Paragraphs.Add(p);
document.SaveToFile(@"c:\temp\x\" + pCount + ".docx", FileFormat.Docx);
}
}
}
我在 15 秒内创建了 1200 个单词的文档:
static void Main()
{
for(int i = 0; i < 1200; i++){
Document document = new Document();
Section s = document.AddSection();
Paragraph p = s.AddParagraph();
TextRange textRange1 = p.AppendText(Guid.NewGuid().ToString());
textRange1.CharacterFormat.TextColor = Color.Blue;
textRange1.CharacterFormat.FontSize = 15;
textRange1.CharacterFormat.Bold = true;
TextRange textRange2 = p.AppendText(Guid.NewGuid().ToString());
textRange2.CharacterFormat.TextColor = Color.Black;
textRange2.CharacterFormat.FontSize = 10;
TextRange textRange3 = p.AppendText(Guid.NewGuid().ToString());
textRange3.CharacterFormat.TextColor = Color.Red;
textRange3.CharacterFormat.FontSize = 8;
textRange3.CharacterFormat.Italic = true;
document.SaveToFile(@"c:\temp\x\" + i + ".docx", FileFormat.Docx);
Console.Out.Write("\r" + i);
}
}
我确实注意到正在进行大量的垃圾收集。减少它可能会加快速度,如果你能弄清楚如何
推荐阅读
- google-cloud-platform - 在 GCP 中将数据从 VM 实例传输到 BigQuery
- r - 如何在插入符号或 tidymodels 中使用 LASSO 进行嵌套交叉验证?
- r - 使用鼠标输入大型数据帧时出错
- c# - 为什么在通过 dotnet CLI 运行 ASP.NET Core 应用程序时看到项目目录名称而不是 dotnet(进程外)?
- flutter - AppBar内的后退按钮在颤动中显示黑屏
- javascript - JavaScript:垂直遍历多维数组
- python-3.x - 没有安装候选时如何将 libpcre3-dev 添加到 docker 映像 python3.8-slim
- javascript - 单击单词以选择并作为答案提交
- apache-kafka - 我如何像关系数据库一样使用 Kafka
- django - 自动将 django 中的 user_id 和 date 字段更新到数据库中