任务
从.doc,.docx和.pdf文件中提取文本,并将内容上载到Azure SQL数据库。需要快速处理其数百万个文档。
问题
如果其中一个文档有问题,脚本将开始失败。我遇到的一些是:
脚本
首先,我生成一个包含100个文件路径的文件列表。这样一来,如果我需要停止执行和/或出现错误,我可以继续执行:
## Word object
if (!($continue)) {
$files = (Get-ChildItem -force -recurse $documentFolder -include *.doc, *.docx).fullname
$files | Out-File (Join-Path $PSScriptRoot "\documents.txt")
$i=0; Get-Content $documentFile -ReadCount 100 | %{$i++; $_ | Out-File (Join-Path $PSScriptRoot "\FileLists\documents_$i.txt")}
}
然后,我将DisplayAlerts标志设置为0来创建ComObject(我认为这会解决该问题。没有)
$word = New-Object -ComObject word.application
$word.Visible = $false
$saveFormat = [Enum]::Parse([Microsoft.Office.Interop.Word.WdSaveFormat], "wdFormatText")
$word.DisplayAlerts = 0
此后,我遍历每个列表中的每个文件,将文件另存为.txt到temp文件夹,提取文本并生成SQL INSERT状态:
foreach ($file in (Get-Content $list)) {
Try {
if ($file -like "*-*") {
Write-Output "Processing: $($file)"
$doc = $word.Documents.Open($file)
$fileName = [io.path]::GetFileNameWithoutExtension($file)
$fileName = $filename + ".txt"
$doc.SaveAs("$env:TEMP\$fileName", [ref]$saveFormat)
$doc.Close()
$4ID = $fileName.split('-')[-1].replace(' ', '').replace(".txt", "")
$text = Get-Content -raw "$env:TEMP\$fileName"
$text = $text.replace("'", "")
$query += "
('$text', $4ID),"
Remove-Item -Force "$env:TEMP\$fileName"
}
<# Upload to azure #>
$query = $query.Substring(0,$query.Length-1)
$query += ";"
$params = @{
'Database' = $TRIS5DATABASENAME
'ServerInstance' = $($AzureServerInstance.FullyQualifiedDomainName)
'Username' = $AdminLogin
'Password' = $InsecurePassword
'query' = $query
}
Invoke-Sqlcmd @params -ErrorAction "continue"
$query = "INSERT INTO tmp_CachedText (tCachedText, tOID)
VALUES "
}
Catch {
Write-Host "$($file) failed to process" -ForegroundColor RED;
}
}
Remove-Item -Force $list.FullName
问题
如上所述,如果其中一个文件出了点问题,或者文档无法在以前的运行中正确打开,则脚本将开始失败。从循环开始,循环中的所有内容都会引发错误:
You cannot call a method on a null-valued expression.
At D:\OneDrive\Scripts\Microsoft Cloud\CachedText-Extraction\CachedText-Extraction.ps1:226 char:13
+ $doc = $word.Documents.Open($file)
基本上我想要的是一种通过在文件有错误时跳过文件来阻止这些错误出现的方法。另外,如果有一种更好的方法可以使用PowerShell从文档文件中提取文本,而不使用同样好的单词。
其中一个错误消息的示例:
这将导致文件被锁定并暂停执行。解决该问题的唯一方法是杀死单词,然后导致脚本其余部分失败。