0

我有一个简单的业务需求来设计一个“名册”电子表格,该电子表格可以由 powershell 脚本读取,以提取下游流程的数据。该电子表格有一些标题,例如 FirstName、LastName、Company、StartDate。这些标头从 A1 开始并继续到 J1。电子表格是 2007 (xlsm),包含 1 个带有格式化表格 (DataTable?) 的工作表。DataTable 的右侧是一些字段,例如 NumberOfRecords 和 ContactInfo。

到目前为止,只要 DataTable 是第一列/行,powershell 脚本就可以正常工作。如果我将 NumberOfRecords & ContactInfo 字段切换到上方或左侧,那么它会打乱整个记录读取顺序。

以下是当前脚本

function getData {
$excelPath = "c:\temp\Roster.xlsm"
$global:roster = @()

$conn = new-object System.Data.OleDb.OleDbConnection
$conn.ConnectionString = 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+$excelPath+';Extended Properties="Excel 12.0 Xml;HDR=YES";'

$cmd = new-object System.Data.OleDb.OleDbCommand("SELECT * FROM [Roster$] WHERE [Valid] = true",$conn)
$conn.open()

$reader = $cmd.ExecuteReader()
while ($reader.Read())
{
    $user = new-object object
    $user | add-member -MemberType NoteProperty -Name "FirstName" -Value $reader.item(1).ToString()
    $user | add-member -MemberType NoteProperty -Name "MName" -Value $reader.item(2).ToString()
    $user | add-member -MemberType NoteProperty -Name "LastName" -Value $reader.item(3).ToString()
    $user | add-member -MemberType NoteProperty -Name "Company" -Value $reader.item(6).ToString()
    $user | add-member -MemberType NoteProperty -Name $reader.GetName(8) -Value $reader.item(8).ToString()
    $global:roster += $user
}

$conn.close()

$global:roster | out-gridview
#
}

有什么办法可以直接引用这个 DataTable 吗?我知道在 Excel 2010 中将数据格式化为表格时,您可以为其命名(默认 Table1)。我可以做类似的事情"SELECT Table1.* FROM [Roster$] WHERE [VALUE] = true"吗?

我的目标是提供一个格式良好的电子表格,通过 Powershell 从格式化表中提取数据。

4

1 回答 1

0

我找到了一个解决方案,但它需要使用 COM 而不是 OLEDB 或 ADO。我无法使用 OLE 在线找到任何解决方案来调用命名对象。这个解决方案要好一些,因为我可以在工作表中的任何位置安排我的 DataTable,但是我不太喜欢它,因为它需要安装 Office,但基本上我可以通过创建 Excel 对象来调用对命名表的引用和然后在 ActiveSheet 上调用它的 ListObjects。这将返回包含所有列/行/范围的 DataTable。然后我需要做的就是遍历每一行和每一列来获取数据。

$excel = new-object -ComObject Excel.Application
$tmp = $excel.Workbooks.Open('c:\temp\Roster.xlsm')
$table = $excel.ActiveSheet.ListObjects | where-object { $_.DisplayName -eq "MyNamedRange" }    
$rows = $table.ListRows
于 2012-05-15T19:55:25.477 回答