广告位联系
返回顶部
分享到

怎么利用PowerShell提取wps表格中嵌入的图片

PowerShell 来源:互联网 作者:佚名 发布时间:2024-11-29 21:06:24 人浏览
摘要

针对Excel下打开表格图片显示 #NAME?编辑栏显示为 =@_xlfn.DISPIMG( 样公式的问题,一般需要在 wps 程序下,Ctrl+F 查找范围选值,输入 =DISPIMG 全选,然后再右键转换为浮动图片。如果是Excel中,则是

针对Excel下打开表格图片显示 #NAME?编辑栏显示为 =@_xlfn.DISPIMG( 样公式的问题,一般需要在 wps 程序下,Ctrl+F 查找范围选值,输入 =DISPIMG 全选,然后再右键转换为浮动图片。如果是Excel中,则是查找公式 DISPIMG。

查阅网上得资料得知,可以通过解压表格文件,然后 根据公式中的第一参数(通常以 ID 开头)看 xl_rels\cellimages.xml.rels 目录下的 name (其值为 dispimg 函数的第一参数)和 r:embed (其值以 rId 开头)的对应关系,然后再看 Id ( rId 开头 ) 和 Target(图片路径) 的对应关系,进而得到图片的路径。

在 LLM 的帮助下进而有以下 PS 脚本。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

function Get-ExcelDispImages {

    param (

        [Parameter(Mandatory=$true)]

        [string]$ExcelPath,

         

        [Parameter(Mandatory=$false)]

        [string]$OutputFolder = ".\ExcelImages"

    )

 

    # 辅助函数:安全地读取文件内容

    function Read-FileContent {

        param (

            [string]$Path

        )

        try {

            # 使用.NET方法直接读取文件,避免PowerShell路径解析问题

            if ([System.IO.File]::Exists($Path)) {

                return [System.IO.File]::ReadAllText($Path)

            }

            Write-Host "File not found: $Path" -ForegroundColor Yellow

            return $null

        }

        catch {

            Write-Host "Error reading file $Path : $_" -ForegroundColor Yellow

            return $null

        }

    }

 

    try {

        # 验证Excel文件是否存在

        if (-not (Test-Path -LiteralPath $ExcelPath)) {

            throw "Excel file not found: $ExcelPath"

        }

 

        # 确保ExcelPath是绝对路径

        $ExcelPath = (Get-Item $ExcelPath).FullName

 

        # 创建输出文件夹(使用绝对路径)

        $OutputFolder = [System.IO.Path]::GetFullPath($OutputFolder)

        if (-not (Test-Path -Path $OutputFolder)) {

            New-Item -ItemType Directory -Path $OutputFolder -Force | Out-Null

        }

 

        # 创建Excel COM对象

        $excel = New-Object -ComObject Excel.Application

        $excel.Visible = $false

        $excel.DisplayAlerts = $false

        $workbook = $excel.Workbooks.Open($ExcelPath)

         

        # 用于存储找到的DISPIMG ID和信息

        $dispImgIds = @()

        $imageMapping = @{}

 

        # 遍历所有工作表

        foreach ($worksheet in $workbook.Worksheets) {

            $usedRange = $worksheet.UsedRange

            $rowCount = $usedRange.Rows.Count

            $colCount = $usedRange.Columns.Count

             

            for ($row = 1; $row -le $rowCount; $row++) {

                for ($col = 1; $col -le $colCount; $col++) {

                    $cell = $usedRange.Cells($row, $col)

                    $formula = $cell.Formula

                     

                    # 检查是否包含DISPIMG函数并提取所有参数

                    if ($formula -match 'DISPIMG\("([^"]+)"') {

                        $imageId = $matches[1]

                        Write-Host "Found DISPIMG: $formula" -ForegroundColor Gray

                         

                        # 创建参数列表

                        $params = @{

                            'ID' = $imageId

                            'Cell' = $cell.Address()

                            'Formula' = $formula

                            'Worksheet' = $worksheet.Name

                        }

                         

                        # 提取所有参数,包括图片ID

                        $paramValues = @()

                        $formula -match 'DISPIMG\((.*?)\)' | Out-Null

                        $paramString = $matches[1]

                        $paramValues = $paramString -split ',' | ForEach-Object {

                            $_ -replace '"', '' -replace '^\s+|\s+$', ''

                        }

                         

                        # 存储所有参数

                        for ($i = 0; $i -lt $paramValues.Count; $i++) {

                            $params["Param$i"] = $paramValues[$i]

                        }

                         

                        $imageMapping[$imageId] = $params

                        $dispImgIds += $imageId

                    }

                }

            }

        }

 

        # 创建临时目录

        $tempPath = Join-Path ([System.IO.Path]::GetTempPath()) "ExcelTemp"

        if (Test-Path $tempPath) {

            Remove-Item $tempPath -Recurse -Force

        }

        New-Item -ItemType Directory -Path $tempPath -Force | Out-Null

 

        # 复制Excel文件到临时目录并解压

        $tempExcel = Join-Path $tempPath "temp.xlsx"

        $tempZip = Join-Path $tempPath "temp.zip"

        Copy-Item -Path $ExcelPath -Destination $tempExcel -Force

        if (Test-Path $tempZip) { Remove-Item $tempZip -Force }

        Rename-Item -Path $tempExcel -NewName "temp.zip" -Force

        Expand-Archive -Path $tempZip -DestinationPath $tempPath -Force

 

        # 检查media文件夹并处理图片

        $mediaPath = Join-Path $tempPath "xl\media"

        if (Test-Path $mediaPath) {

            # 显示DISPIMG参数和图片对应关系

            Write-Host "`nFound $($imageMapping.Count) DISPIMG functions" -ForegroundColor Cyan

             

            if ($imageMapping.Count -gt 0) {

                Write-Host "`n=== DISPIMG Functions Found ===" -ForegroundColor Cyan

                Write-Host "Found $($imageMapping.Count) DISPIMG functions" -ForegroundColor Cyan

                 

                # 显示所有找到的DISPIMG函数

                Write-Host "`n=== DISPIMG Functions Details ===" -ForegroundColor Yellow

                foreach ($id in $imageMapping.Keys) {

                    $params = $imageMapping[$id]

                    Write-Host "Cell: [$($params.Worksheet)]$($params.Cell)" -ForegroundColor Gray

                    Write-Host "Formula: $($params.Formula)" -ForegroundColor Gray

                }

                 

                # 首先从cellimages.xml获取DISPIMG ID到rId的映射

                $dispImgToRid = @{}

                $cellImagesPath = Join-Path $tempPath "xl\cellimages.xml"

                Write-Host "`n=== Reading cellimages.xml ===" -ForegroundColor Yellow

                Write-Host "Path: $cellImagesPath" -ForegroundColor Gray

                 

                if (Test-Path $cellImagesPath) {

                    try {

                        $xmlContent = Get-Content $cellImagesPath -Raw -EnCoding UTF8

                        Write-Host "`nRaw XML Content:" -ForegroundColor Gray

                        Write-Host $xmlContent

                         

                        # 使用正则表达式提取所有cellImage元素

                        $matches = [regex]::Matches($xmlContent, '<etc:cellImage>.*?</etc:cellImage>', [System.Text.RegularExpressions.RegexOptions]::Singleline)

                        Write-Host "`nFound $($matches.Count) cellImage elements" -ForegroundColor Gray

                         

                        foreach ($match in $matches) {

                            $cellImageXml = $match.Value

                            Write-Host "`nProcessing cellImage element:" -ForegroundColor Gray

                             

                            # 提取name属性(包含DISPIMG ID)

                            if ($cellImageXml -match 'name="([^"]+)"') {

                                $dispImgId = $matches[1]

                                Write-Host "Found DISPIMG ID: $dispImgId" -ForegroundColor Gray

                                 

                                # 提取r:embed属性(包含rId)

                                if ($cellImageXml -match 'r:embed="(rId\d+)"') {

                                    $rId = $matches[1]

                                    $dispImgToRid[$dispImgId] = $rId

                                    Write-Host "  Mapping: DISPIMG ID $dispImgId -> rId $rId" -ForegroundColor Green

                                }

                            }

                        }

                    }

                    catch {

                        Write-Host "Error reading cellimages.xml: $($_.Exception.Message)" -ForegroundColor Red

                        Write-Host $_.Exception.StackTrace -ForegroundColor Red

                    }

                }

                else {

                    Write-Host "cellimages.xml not found!" -ForegroundColor Red

                }

                 

                # 从cellimages.xml.rels获取rId到实际图片的映射

                $ridToImage = @{}

                $cellImagesRelsPath = Join-Path $tempPath "xl\_rels\cellimages.xml.rels"

                Write-Host "`n=== Reading cellimages.xml.rels ===" -ForegroundColor Yellow

                Write-Host "Path: $cellImagesRelsPath" -ForegroundColor Gray

                 

                if (Test-Path $cellImagesRelsPath) {

                    try {

                        [xml]$relsXml = Get-Content $cellImagesRelsPath -Raw

                        Write-Host "`nXML Content:" -ForegroundColor Gray

                        Write-Host $relsXml.OuterXml

                         

                        $relsXml.Relationships.Relationship | ForEach-Object {

                            if ($_.Target -match "media/") {

                                $ridToImage[$_.Id] = $_.Target

                                Write-Host "  rId $($_.Id) -> $($_.Target)" -ForegroundColor Green

                            }

                        }

                    }

                    catch {

                        Write-Host "Error reading cellimages.xml.rels: $($_.Exception.Message)" -ForegroundColor Red

                        Write-Host $_.Exception.StackTrace -ForegroundColor Red

                    }

                }

                else {

                    Write-Host "cellimages.xml.rels not found!" -ForegroundColor Red

                }

                 

                Write-Host "`n=== Summary of Mappings ===" -ForegroundColor Yellow

                Write-Host "DISPIMG ID -> rId mappings:" -ForegroundColor Gray

                $dispImgToRid.GetEnumerator() | ForEach-Object {

                    Write-Host "  $($_.Key) -> $($_.Value)" -ForegroundColor Gray

                }

                 

                Write-Host "`nrId -> Image mappings:" -ForegroundColor Gray

                $ridToImage.GetEnumerator() | ForEach-Object {

                    Write-Host "  $($_.Key) -> $($_.Value)" -ForegroundColor Gray

                }

                 

                # 处理每个DISPIMG函数

                Write-Host "`n=== Processing DISPIMG Functions ===" -ForegroundColor Yellow

                foreach ($id in $imageMapping.Keys) {

                    $params = $imageMapping[$id]

                     

                    Write-Host "`nProcessing: [$($params.Worksheet)]$($params.Cell)" -ForegroundColor Green

                    Write-Host "Formula: $($params.Formula)" -ForegroundColor Gray

                    Write-Host "DISPIMG ID: $id" -ForegroundColor Gray

                     

                    # 从DISPIMG ID查找对应的rId

                    $rId = $dispImgToRid[$id]

                    if ($rId) {

                        Write-Host "Found rId: $rId" -ForegroundColor Green

                         

                        # 从rId查找对应的图片路径

                        $imagePath = $ridToImage[$rId]

                        if ($imagePath) {

                            Write-Host "Found image path: $imagePath" -ForegroundColor Green

                            $imageName = Split-Path $imagePath -Leaf

                             

                            # 查找对应的图片文件

                            $mediaFile = Get-ChildItem -LiteralPath $mediaPath | Where-Object { $_.Name -eq $imageName }

                            if ($mediaFile) {

                                $outputPath = Join-Path $OutputFolder "$id$($mediaFile.Extension)"

                                Copy-Item -LiteralPath $mediaFile.FullName -Destination $outputPath -Force

                                Write-Host "Successfully copied: $imageName -> $outputPath" -ForegroundColor Cyan

                           #    以 media 文件夹下的文件名复制

                           #    Copy-Item  $mediaFile.FullName  $(Join-Path $OutputFolder $(Split-Path $imagePath -Leaf))

                            }

 

                            else {

                                Write-Host "Image file not found: $imageName" -ForegroundColor Red

                            }

                        }

                        else {

                            Write-Host "No image path found for rId: $rId" -ForegroundColor Red

                        }

                    }

                    else {

                        Write-Host "No rId found for DISPIMG ID: $id" -ForegroundColor Red

                    }

                }

            } else {

                Write-Host "No DISPIMG functions found in the workbook." -ForegroundColor Yellow

            }

        }

    }

    catch {

        Write-Host "错误: $($_.Exception.Message)" -ForegroundColor Red

    }

    finally {

        # 清理

        if ($workbook) {

            $workbook.Close($false)

        }

        if ($excel) {

            $excel.Quit()

            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null

        }

        if (Test-Path $tempPath) {

            Remove-Item $tempPath -Recurse -Force

        }

        [System.GC]::Collect()

        [System.GC]::WaitForPendingFinalizers()

    }

}

一个可能的用法如下

Get-ExcelDispImages -ExcelPath "C:\Users\demo\Documents\dispimg_wps.xlsx" -OutputFolder $pwd\output

生成的图片在当前目录下的 output 文件夹下。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 :
相关文章
  • Python+PIL实现批量在图片上写上自定义文本

    Python+PIL实现批量在图片上写上自定义文本
    1、库的介绍 Pillow 是一个 Python 的图像处理库,它是 Python Imaging Library (PIL) 的一个分支,并且增加了更多的功能。Pillow 库使得加载、操作和
  • 怎么利用PowerShell提取wps表格中嵌入的图片
    针对Excel下打开表格图片显示 #NAME?编辑栏显示为 =@_xlfn.DISPIMG( 样公式的问题,一般需要在 wps 程序下,Ctrl+F 查找范围选值,输入 =DISPIMG 全
  • 脚本实现SSL证书到期监控介绍

    脚本实现SSL证书到期监控介绍
    1)准备工作 创建一个企业微信账号,并创建一个组,在组里面配置企业微信提供的机器人。将机器人提供的 WebHook 地址保存。 2)编写脚本
  • 远程脚本的详细介绍
    实际上,我们自己也曾用过这种方法。这在以前一般称为远程脚本(remote scripting),很多人认为这只是一种修修补补。不过,这确实提供了
  • CS1.5,cs1.6中使用包含文件夹的脚本的图文教程

    CS1.5,cs1.6中使用包含文件夹的脚本的图文教程
    我们继续教大家如何使用含有文件夹的脚本比如你下载的是这样的脚本文件 或者 一,自动安装脚本文件 我们网站制作了一个.exe安装文件的
  • 使用powershell创建虚拟机的介绍

    使用powershell创建虚拟机的介绍
    在进行与 azure 相关的自动化过程中,创建虚拟主机是避不开的操作。由于系统本身的复杂性,很难用一两条简单的命令完成虚拟主机的创建
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计