首页 > 其他分享 >再聊 word 文档中无法显示链接的图像问题

再聊 word 文档中无法显示链接的图像问题

时间:2024-12-06 18:44:19浏览次数:9  
标签:word Package Get 再聊 Write _. Host 文档 链接

之前对 docx 文档困扰的问题,现象表现为——
无法显示链接的图像。该文件可能已被移动、重命名或删除。请验证该链接是否指向正确的文件和位置。
The linked image cannot be displayed. The file may have been moved, renamed, or deleted. Verify that the link points to the correct file and location.

image_display_error

先前,wps文字表格邮件附件部分图片无法预览的问题(1),提到的问题,没想到简单的编辑指向文件的链接方法就能解决。
文件-信息-编辑指向文件的链接,选中将文件保存在文档中,以及选中待处理的链接条目,断开链接。

vba 查看图片源文件路径与转换链接

Sub DisplayLinkedImageNameAndUnlink()
    Dim shp As Shape
    ' 打印内联形状和形状的数量
    Debug.Print "InlineShapes Count: " & ActiveDocument.InlineShapes.Count
    Debug.Print "Shapes Count: " & ActiveDocument.Shapes.Count
    ' 遍历形状集合
    For Each shp In ActiveDocument.Shapes
        With shp
            ' 检查形状是否为链接的图片
            If shp.Type = msoLinkedPicture Then
                
                ' 打印源文件名、备选文本和名称
                Debug.Print "Target: " & shp.LinkFormat.SourceFullName
                Debug.Print "descr: " & shp.AlternativeText
                Debug.Print "Name: " & shp.Name
                '更新链接
                shp.LinkFormat.Update
                shp.LinkFormat.SavePictureWithDocument = True
                ' 解除链接
                shp.LinkFormat.BreakLink
                
                ActiveDocument.UndoClear
                
            End If
        End With
    Next
    
    ' 遍历内联形状集合
    For j = ActiveDocument.InlineShapes.Count To 1 Step -1
        ' 检查内联形状是否为链接的图片
        If ActiveDocument.InlineShapes(j).Type = wdInlineShapeLinkedPicture Then
            ' 打印备选文本和源文件名
            Debug.Print "descr: " & ActiveDocument.InlineShapes(j).AlternativeText
            Debug.Print "Target: " & ActiveDocument.InlineShapes(j).LinkFormat.SourceFullName
            ActiveDocument.InlineShapes(j).LinkFormat.Update
            ' unlink the inlineshape picture
            ActiveDocument.InlineShapes(j).LinkFormat.SavePictureWithDocument = True
            
            ActiveDocument.InlineShapes(j).LinkFormat.BreakLink
            
            ActiveDocument.UndoClear
        End If
    Next j
    '保存当前活动文档
    ActiveDocument.Save
End Sub



使用 Powershell 的一些练习

# 打开Word文档作为一个压缩包
$WordPackage = [System.IO.Packaging.Package]::Open("C:\Users\demo\问题-无法显示链接的图片.docx")

# 定义一个函数,用于从压缩包中提取指定部分的内容
function Get-ZipPart {
    param (
        [string]$PartUri
    )
    $dataStream = New-Object System.IO.MemoryStream
    $WordPackage.GetPart($PartUri).GetStream().CopyTo($dataStream)
    return [System.Text.Encoding]::UTF8.GetString($dataStream.ToArray())
}

# 提取 document.xml.rels 中的关系信息
$Relationships = Get-ZipPart "/word/_rels/document.xml.rels" | Select-Xml -XPath "//ns:Relationship/@Id | //ns:Relationship/@Target" -Namespace @{ns='http://schemas.openxmlformats.org/package/2006/relationships'} | ForEach-Object { $_.Node.Value }

# 提取 document.xml 中的图片描述信息
$ImageDescriptions = Get-ZipPart "/word/document.xml" | Select-Xml -XPath "//pic:cNvPr/@descr" -Namespace @{pic='http://schemas.openxmlformats.org/drawingml/2006/picture'} | ForEach-Object { $_.Node."#text" }

# 输出结果
$Relationships
$ImageDescriptions

docx_images_info
再进一步,由 大语言模型 Claude 深化一下,则有,

# 定义命名空间
$namespaces = @{
    rel = 'http://schemas.openxmlformats.org/package/2006/relationships'
    pic = 'http://schemas.openxmlformats.org/drawingml/2006/picture'
    a = 'http://schemas.openxmlformats.org/drawingml/2006/main'
    wp = 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing'
}

function Get-WordPackage {
    param (
        [Parameter(Mandatory=$true)]
        [string]$FilePath
    )
    
    try {
        return [System.IO.Packaging.Package]::Open($FilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
    }
    catch {
        Write-Error "无法打开文件: $FilePath"
        Write-Error $_.Exception.Message
        return $null
    }
}

function Get-PackagePartContent {
    param (
        [Parameter(Mandatory=$true)]
        [System.IO.Packaging.Package]$Package,
        [Parameter(Mandatory=$true)]
        [string]$PartPath
    )
    
    try {
        $part = $Package.GetPart($PartPath)
        $stream = New-Object System.IO.MemoryStream
        $part.GetStream().CopyTo($stream)
        return [System.Text.Encoding]::UTF8.GetString($stream.ToArray())
    }
    catch {
        Write-Error "无法读取部分: $PartPath"
        Write-Error $_.Exception.Message
        return $null
    }
}

function Get-ImageRelationships {
    param (
        [Parameter(Mandatory=$true)]
        [System.IO.Packaging.Package]$Package
    )
    
    $relsContent = Get-PackagePartContent -Package $Package -PartPath "/word/_rels/document.xml.rels"
    if ($relsContent) {
        $relationships = Select-Xml -Content $relsContent -XPath "//rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/image']" -Namespace $namespaces
        
        return $relationships | ForEach-Object {
            @{
                Id = $_.Node.Id
                Target = $_.Node.Target
                TargetMode = $_.Node.TargetMode
            }
        }
    }
    return $null
}

function Get-ImageDescriptions {
    param (
        [Parameter(Mandatory=$true)]
        [System.IO.Packaging.Package]$Package
    )
    
    $docContent = Get-PackagePartContent -Package $Package -PartPath "/word/document.xml"
    if ($docContent) {
        return Select-Xml -Content $docContent -XPath "//pic:cNvPr" -Namespace $namespaces | ForEach-Object {
            @{
                Id = $_.Node.id
                Name = $_.Node.name
                Description = $_.Node.descr
            }
        }
    }
    return $null
}

function Get-WordImageInfo {
    param (
        [Parameter(Mandatory=$true)]
        [string]$FilePath
    )
    
    $package = Get-WordPackage -FilePath $FilePath
    if (-not $package) { return }
    
    try {
        Write-Host "=== Word文档图片信息 ===" -ForegroundColor Green
        Write-Host "文件: $FilePath" -ForegroundColor Green
        Write-Host "------------------------"
        
        # 获取图片关系
        Write-Host "`n图片关系:" -ForegroundColor Yellow
        $relationships = Get-ImageRelationships -Package $package
        $relationships | ForEach-Object {
            Write-Host "ID: $($_.Id)"
            Write-Host "目标: $($_.Target)"
            if ($_.TargetMode) {
                Write-Host "目标模式: $($_.TargetMode)"
            }
            Write-Host "------------------------"
        }
        
        # 获取图片描述
        Write-Host "`n图片描述:" -ForegroundColor Yellow
        $descriptions = Get-ImageDescriptions -Package $package
        $descriptions | ForEach-Object {
            Write-Host "ID: $($_.Id)"
            Write-Host "名称: $($_.Name)"
            if ($_.Description) {
                Write-Host "描述: $($_.Description)"
            }
            Write-Host "------------------------"
        }
        
        # 检查链接图片
        Write-Host "`n链接状态检查:" -ForegroundColor Yellow
        $relationships | Where-Object { $_.TargetMode -eq 'External' } | ForEach-Object {
            $target = $_.Target
            if (Test-Path $target) {
                Write-Host "链接正常: $target" -ForegroundColor Green
            }
            else {
                Write-Host "链接断开: $target" -ForegroundColor Red
            }
            Write-Host "------------------------"
        }
    }
    finally {
        $package.Close()
    }
}

# 使用示例
# Get-WordImageInfo -FilePath "C:\Users\demo\Documents\question_images.docx"

P.s. 有一个现象是,本地链接中长路径会用 8.3 短文件名命名规则,如果原来的路径丢失,可以重建路径(需要注意访问权限),同时文件内容就未必和原始的一致了。使用 dir /x 命令可以查看短地址,单行命令 for %i in ("C:\Program Files") do @echo %~si,或者用 powershell,比如 (New-Object -com scripting.filesystemobject).getfolder('C:\Program Files').shortname 得到 Program Files 的短路径 PROGRA~1。

搜索“AppData\Local\Temp\ksohtml\clip_image”,可以发现网上有许多错误使用 wps 文档(没有转换为非链接图片)复制粘贴而造成图片无法显示而影响正常阅读的。

参考或延申阅读:

Transform linked images to embedded images
Break link to picture programatically in MS Word 2010
How to convert all linked images to embedded in Word document?
PPT中用vba批量断开外部链接及更改链接路径的方法
8.3 Filename
How can I find the short path of a Windows directory/file?

标签:word,Package,Get,再聊,Write,_.,Host,文档,链接
From: https://www.cnblogs.com/geyee/p/18591298

相关文章

  • 利用pdf.js +FastAPI+openai-TTS 搭建 在线PDF 文档语音阅读服务
    之前一直用NuturalReader阅读英文pdf,校准英文单词发音的准确性,无奈NuturalReader的LLM真人语音价格太贵了,一年要有110刀。实在肉疼。最近基于ManyiAPI聚合接口站:https://api.manyi88.top,ManyiAPI注册链接(注册优惠)可以直接调用openai的tts服务,就有了自己写个在线语音阅读pd......
  • [开发工具]Idea实用操作文档,工欲善其事必先利其器
    [Java开发]提升开发效率的IDEA插件与功能设置技巧在Java开发中,良好的开发环境配置和工具使用可以大大提高开发效率。IDEA作为目前最流行的Java开发工具,其丰富的插件和功能为开发者提供了不少便利。本文将分享如何通过IDEA的功能配置和插件使用来提升编码效率和质量。一、IDE......
  • Y20030029 Java+微信+SPRINGBOOT+MYSQL+LW+传统文化展示微信小程序的设计与开发 配置
    传统文化展示微信小程序1.项目摘要2.课题开发的背景和意义3.项目功能4.界面展示5.源码获取1.项目摘要基于微信小程序的传统文化展示小程序是一个集合了多种传统文化元素与现代化技术的创新平台。它充分利用了微信小程序的便捷性和普及性,为广大用户提供了一个深入......
  • 一些写得不错的关于项目文档编写的博客
    阮一峰(GitHub,提供md格式)https://github.com/ruanyf/document-style-guide曾左(博客园,格式可参考)https://www.cnblogs.com/zengzuo613/p/18589348天下尽好(博客园,目录可参考)https://www.cnblogs.com/Little-Li/archive/2011/06/30/2094230.htmlJ-ljn(博客......
  • 【服务器监控】grafana+Prometheus+node exporter详细部署文档
    我们在进行测试时,不可能一直手动看着服务器的性能消耗,这时候就需要有个工具替我们监控服务器的性能消耗。这里记录下grafana+Prometheus+nodeExporter的组合用于监控服务器。简单介绍:grafana:看板工具,所有采集的性能数据都会展示在这个看板上,官网:linkPrometheus:监控系......
  • 基于SSM的汽车在线租赁系统【附源码+文档】
    ......
  • 基于SSM的多用户个人博客网站【附源码+文档】
    ......
  • 文档协作噩梦?用Excel实时编辑说再见!
    曾经,你是否在工作中因为多人编辑Excel文档而频频翻车?无休止的文件版本号(如“表格V1.1.1_final_final”)让协作变得复杂而低效。现在,这种混乱可以通过多人协同编辑彻底解决。多人协同编辑Excel允许所有团队成员同时在云端更新同一个表格,每个人的修改都能即时同步。再也不需要繁琐的......
  • 重磅更新!微信公众号文章批量下载工具2.0版,轻松导出html、word、pdf文档!
    声明该软件仅用于学习交流使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与软件作者无关!如果您想要转载下载文章,请务必获得原作者的授权!本文章未经许可禁止转载,擅自使用本文讲解的软件而导致的任何意外,作者均不负责,若有侵权,请在公众号【程序员王哪跑】联系作者立即删......
  • 为WordPress网站优化性能的最佳CDN集成服务
    在数字化竞争激烈的今天,WordPress网站作为全球最受欢迎的内容管理系统之一,深受企业和个人的青睐。然而,随着网站流量和内容复杂性的增加,性能优化成为每一个站长的必修课。CDN(内容分发网络)集成服务无疑是提升WordPress网站加载速度和安全性的最佳工具之一。接下来一起看看WordP......