用于解压缩 xlsx 并从 sheet xml 文件中读取内容的 Powershell 脚本
Powershell script to unzip xlsx and read contents from a sheet xml file
背景
我正在尝试设计一个无需 Excel 安装或导入 modules/libraries 即可在服务器上 运行 的脚本。这排除了 COM Excel.Application、ImportExcel 模块和其他第 3 方库。相反,我将 excel 文件解压缩到 xml 文件的集合中。我需要在 powershell 中解析这些 xml 文件,以获得跨越多个 Excel sheets.
的给定单元格值范围
到目前为止,我已经编写了一个脚本来检索 sheetID:
unzip myExcel.xlsx
[xml]$workbookXML = Get-Content xl\workbook.xml
[xml]$sheet = Get-Content xl\worksheets\sheet10.xml
$sheetDictionary = @{}
foreach($sheetChildNode in $workbookXML.workbook.sheets.sheet) {
$sheetDictionary.add($sheetChildNode.name, $sheetChildNode.sheetId)
}
$sheetDictionary
我可以使用 sheetID 在 xl\worksheets\sheet.xml 下找到单独的 sheet 文件。我的问题是从这些单独的 sheet 文件中解析和检索值。
示例输入
这里是 xl\worksheets\sheet10.xml 的示例:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<worksheet xr:uid="{00000000-0001-0000-0800-000000000000}"
xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3"
xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2"
xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision"
xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" mc:Ignorable="x14ac xr xr2
xr3" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<dimension ref="A1:L100"/>
<sheetViews>
<sheetView workbookViewId="0">
<selection sqref="A11:B11" activeCell="A11"/>
</sheetView>
</sheetViews>
<sheetFormatPr x14ac:dyDescent="0.35" defaultRowHeight="14.5"/>
<cols>
<col customWidth="1" style="32" width="18.81640625" max="1" min="1"/>
<col style="32" width="8.7265625" max="2" min="2"/>
<col customWidth="1" style="5" width="14.81640625" max="11" min="11"/>
<col customWidth="1" style="5" width="12" max="12" min="12"/>
</cols>
<sheetData>
<row r="6" x14ac:dyDescent="0.35" spans="1:12">
<c r="A6" t="s" s="33">
<v>270</v>
</c>
<c r="B6" t="s" s="33">
<v>271</v>
</c>
<c r="K6" t="s" s="5">
<v>272</v>
</c>
<c r="L6" t="s" s="5">
<v>273</v>
</c>
</row>
<row r="7" x14ac:dyDescent="0.35" spans="1:12">
<c r="A7" t="str" s="32">
<f>'All Parameters'!K13</f>
<v>UnwantedValue1</v>
</c>
<c r="B7" t="str" s="32">
<f>'All Parameters'!L13</f>
<v>UnwantedValue2</v>
</c>
<c r="K7" t="str" s="5">
<f ref="K7:K38" t="shared" si="0">IF(AND(NOT($A7=""),NOT($B7="")),A7,CONCATENATE("ParameterNotUsed",ROW()))</f>
<v>db.url</v>
</c>
<c r="L7" t="str" s="5">
<f ref="L7:L38" t="shared" si="1">IF(AND(NOT($A7=""),NOT($B7="")),B7,CONCATENATE("ParameterNotUsed",ROW()))</f>
<v>URLValue</v>
</c>
</row>
<row r="8" x14ac:dyDescent="0.35" spans="1:12">
<c r="A8" t="str" s="32">
<f>'All Parameters'!O14</f>
<v>UnwantedValue3</v>
</c>
<c r="B8" t="str" s="32">
<f>'All Parameters'!P14</f>
<v>UnwantedValue4</v>
</c>
<c r="K8" t="str" s="5">
<f t="shared" si="0"/>
<v>db.User</v>
</c>
<c r="L8" t="str" s="5">
<f t="shared" si="1"/>
<v>UserName</v>
</c>
</row>
</sheetData>
<pageMargins footer="0.3" header="0.3" bottom="0.75" top="0.75" right="0.7" left="0.7"/>
</worksheet>
我想从此 xml 文件中提取 K7、L7(db.url 和 urlValue)和 K8、L8(db.User 和用户名)。位置在 r 节点中给出,值在 v 节点中给出。
尝试
不幸的是,我无法从 sheet xml 文件中检索任何值。使用这个site,我试过
[xml]$sheet = Get-Content xl\worksheets\sheet10.xml
$data = (Select-Xml -xpath "/worksheet/sheetData/row/c[r = '[K-L][7-9]$|[K-L][1-9][0-9]$|[K-L]100']/v" $sheet |
% {$_.Node.'#text'})
$data
它使用 RegEx 来覆盖 K7:L100,但没有输出。我也尝试过各种其他方法,例如在 xml 文件中点选,但我无法让它们起作用。我愿意接受任何预安装的 PowerShell 编码方法来检索这些值。
非常感谢。
两件事 - 您的 xpath 表达式必须考虑此 xml 中命名空间的存在。另外 - 将正则表达式与 xml.
一起使用绝不是一个好主意
所以请尝试以下方法:
$ns = @{ns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"}
$items = Select-Xml -Xml $sheet -XPath '//ns:c[(@r="K7" or @r="L7" or @r="K8" or @r="L8")]//ns:v' -Namespace $ns
$items | Foreach {$_.Node.InnerXml}
输出:
db.url
URLValue
db.User
UserName
编辑:
要获取 c
属性的属性值,请使用:
$items = Select-Xml -Xml $sheet -XPath '//ns:c[@r]/@r' -Namespace $ns
$items | Foreach {$_.Node}
输出:
A6
B6
K6
L6
A7
B7
K7
L7
A8
B8
K8
L8
背景
我正在尝试设计一个无需 Excel 安装或导入 modules/libraries 即可在服务器上 运行 的脚本。这排除了 COM Excel.Application、ImportExcel 模块和其他第 3 方库。相反,我将 excel 文件解压缩到 xml 文件的集合中。我需要在 powershell 中解析这些 xml 文件,以获得跨越多个 Excel sheets.
的给定单元格值范围到目前为止,我已经编写了一个脚本来检索 sheetID:
unzip myExcel.xlsx
[xml]$workbookXML = Get-Content xl\workbook.xml
[xml]$sheet = Get-Content xl\worksheets\sheet10.xml
$sheetDictionary = @{}
foreach($sheetChildNode in $workbookXML.workbook.sheets.sheet) {
$sheetDictionary.add($sheetChildNode.name, $sheetChildNode.sheetId)
}
$sheetDictionary
我可以使用 sheetID 在 xl\worksheets\sheet
示例输入
这里是 xl\worksheets\sheet10.xml 的示例:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<worksheet xr:uid="{00000000-0001-0000-0800-000000000000}"
xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3"
xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2"
xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision"
xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" mc:Ignorable="x14ac xr xr2
xr3" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<dimension ref="A1:L100"/>
<sheetViews>
<sheetView workbookViewId="0">
<selection sqref="A11:B11" activeCell="A11"/>
</sheetView>
</sheetViews>
<sheetFormatPr x14ac:dyDescent="0.35" defaultRowHeight="14.5"/>
<cols>
<col customWidth="1" style="32" width="18.81640625" max="1" min="1"/>
<col style="32" width="8.7265625" max="2" min="2"/>
<col customWidth="1" style="5" width="14.81640625" max="11" min="11"/>
<col customWidth="1" style="5" width="12" max="12" min="12"/>
</cols>
<sheetData>
<row r="6" x14ac:dyDescent="0.35" spans="1:12">
<c r="A6" t="s" s="33">
<v>270</v>
</c>
<c r="B6" t="s" s="33">
<v>271</v>
</c>
<c r="K6" t="s" s="5">
<v>272</v>
</c>
<c r="L6" t="s" s="5">
<v>273</v>
</c>
</row>
<row r="7" x14ac:dyDescent="0.35" spans="1:12">
<c r="A7" t="str" s="32">
<f>'All Parameters'!K13</f>
<v>UnwantedValue1</v>
</c>
<c r="B7" t="str" s="32">
<f>'All Parameters'!L13</f>
<v>UnwantedValue2</v>
</c>
<c r="K7" t="str" s="5">
<f ref="K7:K38" t="shared" si="0">IF(AND(NOT($A7=""),NOT($B7="")),A7,CONCATENATE("ParameterNotUsed",ROW()))</f>
<v>db.url</v>
</c>
<c r="L7" t="str" s="5">
<f ref="L7:L38" t="shared" si="1">IF(AND(NOT($A7=""),NOT($B7="")),B7,CONCATENATE("ParameterNotUsed",ROW()))</f>
<v>URLValue</v>
</c>
</row>
<row r="8" x14ac:dyDescent="0.35" spans="1:12">
<c r="A8" t="str" s="32">
<f>'All Parameters'!O14</f>
<v>UnwantedValue3</v>
</c>
<c r="B8" t="str" s="32">
<f>'All Parameters'!P14</f>
<v>UnwantedValue4</v>
</c>
<c r="K8" t="str" s="5">
<f t="shared" si="0"/>
<v>db.User</v>
</c>
<c r="L8" t="str" s="5">
<f t="shared" si="1"/>
<v>UserName</v>
</c>
</row>
</sheetData>
<pageMargins footer="0.3" header="0.3" bottom="0.75" top="0.75" right="0.7" left="0.7"/>
</worksheet>
我想从此 xml 文件中提取 K7、L7(db.url 和 urlValue)和 K8、L8(db.User 和用户名)。位置在 r 节点中给出,值在 v 节点中给出。
尝试
不幸的是,我无法从 sheet xml 文件中检索任何值。使用这个site,我试过
[xml]$sheet = Get-Content xl\worksheets\sheet10.xml
$data = (Select-Xml -xpath "/worksheet/sheetData/row/c[r = '[K-L][7-9]$|[K-L][1-9][0-9]$|[K-L]100']/v" $sheet |
% {$_.Node.'#text'})
$data
它使用 RegEx 来覆盖 K7:L100,但没有输出。我也尝试过各种其他方法,例如在 xml 文件中点选,但我无法让它们起作用。我愿意接受任何预安装的 PowerShell 编码方法来检索这些值。
非常感谢。
两件事 - 您的 xpath 表达式必须考虑此 xml 中命名空间的存在。另外 - 将正则表达式与 xml.
一起使用绝不是一个好主意所以请尝试以下方法:
$ns = @{ns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"}
$items = Select-Xml -Xml $sheet -XPath '//ns:c[(@r="K7" or @r="L7" or @r="K8" or @r="L8")]//ns:v' -Namespace $ns
$items | Foreach {$_.Node.InnerXml}
输出:
db.url
URLValue
db.User
UserName
编辑:
要获取 c
属性的属性值,请使用:
$items = Select-Xml -Xml $sheet -XPath '//ns:c[@r]/@r' -Namespace $ns
$items | Foreach {$_.Node}
输出:
A6
B6
K6
L6
A7
B7
K7
L7
A8
B8
K8
L8