见下面的答案
编辑:由于下面的答案,我能够沿着调试的道路走下去,让一些东西正常工作。我现在可以通过以下主要功能独立完成这一点。值得庆幸的是,没有多余的数据,所以正则表达式很好,只需选择正确的表并按照此主函数所示的每一行:
function Main {
# For script modification. Like C/C++ #define preprocessor commands
Set-Variable BLAHBLAH_NUMBER_COLUMN_NUMBER -value ([byte]1) -option Constant
Set-Variable BLAHBLAH_TEXT_COLUMN_NUMBER -value ([byte]2) -option Constant
Set-Variable BLAHBLAHTWO_NUMBER_COLUMN_NUMBER -value ([byte]3) -option Constant
Set-Variable BLAHBLAHTWO_TEXT_COLUMN_NUMBER -value ([byte]4) -option Constant
Set-Variable MOREDATABLAHBLAH_COLUMN_NUMBER -value ([byte]9) -option Constant
Set-Variable IMPORTANT_TABLES_COLUMN_COUNT -value ([byte]9) -option Constant
# Open up word doc with data we want
$tempfilename = "FILENAMEGOESHERE" # For testing
$global:filename = "$($pwd)\$tempfilename"
Write-Host $filename # For testing
$global:Word_Object = New-Object -ComObject Word.Application
$RQ_Object.Visible = $true
$WordDocument = $Word_Object.Documents.Open($filename)
ExcelCOMObjectGen
HeaderGenerationWithPrompt
HeaderFormat
HeaderColoring
ColumnHeadersGeneration
# Find the important table
$ImportantTable = $WordDocument.Tables | Where-Object{$_.Columns.Count -eq $IMPORTANT_TABLES_COLUMN_COUNT}
Write-Host $ImportantTable.Rows.Count "rows with desired prefix"
### THIS BLOCK FOR LOGS FOR DEBUGGING/DEVELOPMENT ###
### THIS BLOCK FOR LOGS FOR DEBUGGING/DEVELOPMENT ###
### THIS BLOCK FOR LOGS FOR DEBUGGING/DEVELOPMENT ###
foreach ($row in $ImportantTable.Rows) {
$printableTextOne = $row.Cells.Item(1).Range.Text
$printableTextTwo = $row.Cells.Item(2).Range.Text
$printToFileText = "$($printableTextOne): $($printableTextTwo)`n"
$printToFileText | Add-Content 'log.txt'
}
### THIS BLOCK FOR LOGS FOR DEBUGGING/DEVELOPMENT ###
### THIS BLOCK FOR LOGS FOR DEBUGGING/DEVELOPMENT ###
### THIS BLOCK FOR LOGS FOR DEBUGGING/DEVELOPMENT ###
}
它正在编写我需要的文本文档的信息,我只需要替换终止字符,然后继续添加其他文档。
开始原始问题 我已经搜索了互联网以及stackoverflow,在这个功能上工作了整整一个工作日。
我正在创建一个powershell脚本来从长度超过100页的Word表中提取数据。如果第1列有某种类型的文本,我想将该行中的单元格导出到Excel文档中。
我可以加载word文档并生成excel文档,但数据输出不正确。
前几页中有些表不是我要解析的~100页表,因此" foreach"线。
Word表格格式如下:
数字|一个文字| B号码| B文字| Data1 |数据2 |等等|
尝试1:
function STACKOVERFLOW {
$WordDocument = $STACKOVERFLOW_Object.Documents.Open($STACKOVERFLOWfilename)
$excelRowCounter = 3
foreach ($table in $WordDocument.Tables) {
$colcount = $table.Columns.Count
# $rowcount = $table.Rows.Count
# the other tables have different numbers of columns, so we can execute this
# block if the table has the right number of columns, defined as constant at start
if ($colcount -eq $IMPORTANT_TABLE_COLUMN_COUNT) {
$A_NUMBER_column_TEMP = $table.cell($excelRowCounter, 1).Range.text
$A_TEXT_column_TEMP = $table.cell($excelRowCounter, 2).Range.text
$B_NUMBER_column_TEMP = $table.cell($excelRowCounter, 3).Range.text
$B_TEXT_column_TEMP = $table.cell($excelRowCounter, 4).Range.text
$worksheet.Cells.Item($excelRowCounter, 4) = "$($A_NUMBER_column_TEMP):`n$A_TEXT_column_TEMP"
$worksheet.Cells.Item($excelRowCounter, 5) = "B Number:`n$($B_NUMBER_column_TEMP):`nB Text:`n$B_TEXT_column_TEMP"
$excelRowCounter++
}
}
}
尝试1成功从Word表格中的第四行拉出,并将相关数据放入excel中所需的单元格中。但它正在跳过2-3行和5-1,000 +
行适用于单行,而不是表中的第一个条目。甚至是第二个。不是一个接一个。
尝试2:
function STACKOVERFLOW {
# using $global:STACKOVERFLOW_Object or $STACKOVERFLOW_object seems to make no difference
# same for $STACKOVERFLOWfilename
$WordDocument = $global:STACKOVERFLOW_Object.Documents.Open($global:STACKOVERFLOWfilename)
$excelRowCounter = 3
$tablerows = $table.Rows.Count
foreach ($table in $WordDocument.Tables) {
if ($table.cell(1, 1).Range.Text -eq "text_in_(1,1)")
{
for (row = 2, $row -le $tablerows, $row++) {
$tempvar = $table.cell($row, 1).Range.Text
$worksheet.Cells.Item($excelRowCounter, 4) = "$tempvar"
# code to enter other cells as desired here.
excelRowCounter++
}
}
}
}
尝试2绝对不会向Excel电子表格打印任何内容。
我也尝试在if语句中使用-like比较无效。
我怀疑尝试2中的问题可能与单词表中的空终止字符有关,例如\ n如何在其他语言中引起类似的问题。
关于我如何做到这一点的任何建议?该表格格式一致,但跨度超过100页或更多。虽然看起来每个页面上出现的列标题都不是问题,但因为什么都没有打印。每页平均大约有10行。
我的下一步尝试可能是使用示例代码在线将表格转换为Excel,然后尝试在Excel文件上运行这些相同的条件
答案 0 :(得分:1)
好的,让我们开始为什么尝试2没有工作。 Word乱七八糟的文字。每个单元格似乎在文本末尾添加了2个字符。我使用了样本表:
A Number A Text B Number B Text Data 1 Data 2
1 Cat 10 Persian White Male
2 Dog 11 Huskey White/Grey Male
3 Pig 12 Potbellied Pink Female
4 Cat 13 Tabby White/Grey/Orange Female
5 Fish 14 Salmon Delicious N/A
我在word doc中添加了一些随机文本,并在此前面添加了另一个带有7列的表。我还设置了一个Excel文档,单元格A1:B2填充了文本,以便我可以添加数据。
我抓住了我想要的桌子,并将其分配给一个变量:
$MyTable = $Document.Tables | Where{$_.Columns.Count -eq 6}
我尝试根据列表Cells.Item(2)
中是否'Cat','Fish'
来匹配行,该列表应返回3行。
$MyTable.Rows | ?{$_.Cells.Item(2).Range.Text -in 'Cat','Fish'}
没有。所以我仔细看了第二行,单元格2文本。
$Animal = $MyTable.Rows.Item(2).Cells.Item(2).Range.Text
$Animal #Returned 'Cat'
$Animal.Length #Returned 5
哇哇,等等,' Cat'不是5个字母。好的,我们有隐形字符,让我们来看看:
$Animal.ToCharArray() | ForEach{"{0} => {1}" -f $_, ([int][char]$_)}
吐了回来:
C => 67
a => 97
t => 116
=> 13
=> 7
一项小小的研究表明,每个细胞都加入了字符13和7。好的,让我们进行正则表达式匹配:
$MyTable.Rows | ?{$_.Cells.Item(2).Range.Text -match 'Cat|Fish'}
这确实返回了3行数据。好吧,但RegEx匹配可能不是最好的方法,因为它可能包含你不想要的东西。因此,让我们只关闭最后2个字符以获得原始值。
$Tail = "{0}{1}$" -f [char][int]13, [char][int]7
$MyTable.Rows | ?{($_.Cells.Item(2).Range.Text -replace $Tail) -in 'Cat','Fish'}
那也返回了所需的3行。现在我们可以在这里使用。那么我只是用ForEach
循环遍历行,并且对于每一行,我转到Excel电子表格上的下一个可用行并逐个单元格复制值(从Word复制/粘贴到Excel变得非常可怕我,所以我只复制了文字。
$MyTable.Rows | ?{($_.Cells.Item(2).Range.Text -replace $Tail) -in 'Cat','Fish'} | %{
$NextRow = $WB.ActiveSheet.Cells.Item(($WB.ActiveSheet.UsedRange.Rows.Count + 1), 1).EntireRow
For($i=1;$i -le $_.Range.Columns.Count;$i++){
$NextRow.Cells.Item($i).value2 = $_.Cells.Item($i).Range.Text -replace $Tail
}
}
这导致所需的行被添加到Excel工作表中。
至于为什么Attempt 1只复制了第四行,它应该只复制第三行,因为$excelRowCounter = 3
。它只复制了一件事,因为你只是通过表循环,而不是通过每个表上的每一行。如果您这样做可能会很好:
if ($colcount -eq $IMPORTANT_TABLE_COLUMN_COUNT) {
For($i = 2; $i -le $Table.Rows.Range.Columns.Count; $i++){
$A_NUMBER_column_TEMP = $table.cell($excelRowCounter, 1).Range.text
$A_TEXT_column_TEMP = $table.cell($excelRowCounter, 2).Range.text
$B_NUMBER_column_TEMP = $table.cell($excelRowCounter, 3).Range.text
$B_TEXT_column_TEMP = $table.cell($excelRowCounter, 4).Range.text
$worksheet.Cells.Item($excelRowCounter, 4) = "$($A_NUMBER_column_TEMP):`n$A_TEXT_column_TEMP"
$worksheet.Cells.Item($excelRowCounter, 5) = "B Number:`n$($B_NUMBER_column_TEMP):`nB Text:`n$B_TEXT_column_TEMP"
$excelRowCounter++
}
}
这会跳过第一行(您可以通过更改2
中的$i = 2
进行调整),并按照您的意图复制所有内容。