Word表格文本中的单元格比较,然后导出数据

时间:2018-01-22 21:34:29

标签: excel powershell ms-word

见下面的答案
编辑:由于下面的答案,我能够沿着调试的道路走下去,让一些东西正常工作。我现在可以通过以下主要功能独立完成这一点。值得庆幸的是,没有多余的数据,所以正则表达式很好,只需选择正确的表并按照此主函数所示的每一行:

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文件上运行这些相同的条件

1 个答案:

答案 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进行调整),并按照您的意图复制所有内容。