【问题标题】:Why would the Excel Interop remove an image after processing a file?为什么 Excel 互操作会在处理文件后删除图像?
【发布时间】:2012-02-09 18:21:44
【问题描述】:

Excel Interop 正在从已处理的文件中删除图像。

我正在使用 Excel 互操作,不存在第三方组件(据我所知)。 工作流程是——创建文件(模板)的副本(目标)、填充单元格、更改单选按钮状态

  1. 为预先存在的 .xslm 文件(模板)创建副本(目标)
  2. 通过 Excel 互操作打开目标
  3. 填充目标单元格,更改单选按钮状态
  4. 带有图像的工作表未修改
  5. 关闭目标

在我的开发机器上,目标文件看起来很棒——所有内容都已填充,图像存在。 注意:在我的开发机器上,我从 VS2010 IDE 运行代码。

在生产机器上 - 一切都已填充,但图像不存在。 相反,以下错误出现在其位置: 注意:在生产机器上,它作为服务运行,使用 Local Service 帐户。

“在文件中未找到关系 ID 为 rId1 的图像部分”

通过以下代码打开整个工作簿:

var workbook = workbooks.Open(targetPath
     0, false, 5, Type.Missing, Type.Missing, false, XlPlatform.xlWindows, "",
     true, false, 0, true, false, false);

请注意,带有图像的工作表未在代码中进行处理。

工作簿(和单个工作表)受到保护。但是,受保护的模板在开发中得到了正确处理,但在生产中却没有。我不认为保护与它有任何关系(但谁知道,对吧?这是 Interop。呃)。

文件是由另一方创建的,所有组件(即图像)都驻留在 .xslm 结构中,而不是作为到另一台服务器的链接。

我已验证该图像在模板文件中的生产机器上可见,但在处理后的文件中不可见。

为了确认这不是在制作中打开文件时出现的问题,我通过电子邮件给自己发送了一份副本,但图像仍然不存在。

我还确认,在我的开发机器上,处理过的文件确实有可见的图像。

我取消了工作表的保护,并解压缩了文件结构。 .jpg 文件确实不存在于生产机器的已处理目标中。

还有一点需要注意——我的开发机器上安装了 Office 2010,而生产机器上安装了 Office 2007。因此,我使用的是 Office 12 Interop。两种环境都不会产生运行时错误。

我使用的是 Interop(而不是 OpenXml 库),因为存在必须填充的 ActiveX 控件。但是请注意,所有 ActiveX 控件都没有任何问题——它们工作正常。它只是从处理过的文件中消失的图像文件(它们在模板文件中渲染得很好)。

更新注意:还有四个其他图像文件,所有 .emf 在不同的工作表上;它们也都被剥离了。

【问题讨论】:

标签: c# excel-2007 excel-2010 excel-interop


【解决方案1】:

Interop is not supported in sever-scenarios by MS.

有很多选项可以在没有 Interop 的情况下读取/编辑/创建 Excel 文件:

MS 提供免费的 OpenXML SDK V 2.0 - 请参阅 http://msdn.microsoft.com/en-us/library/bb448854%28office.14%29.aspx(仅限 XLSX)

这可以读写 MS Office 文件(包括 Excel)。

另一个免费选项请参阅http://www.codeproject.com/KB/office/OpenXML.aspx(仅限 XLSX)

如果您需要更多处理旧版 Excel(例如 XLS,而不仅仅是 XLSX)、渲染、创建 PDF、公式等,那么有不同的免费和商业库,例如 ClosedXML(免费,仅限 XLSX)、@987654325 @(免费,仅限 XLSX)、Aspose.CellsSpreadsheetGearLibXLFlexcel 等。

很难说您的特定情况(ActiveX 控件)是否完全支持上述任何一种...这是您需要测试的东西...

即使任何库都支持 ActiveX 控件,ActiveX 控件本身也有可能无法在 Windows 服务中工作(权限等)。

编辑 - 根据评论:

我了解 ActiveX 问题,我从 2 点解决了它:

  • 您真的测试过上述所有库吗?
  • 您是否与 ActiveX 控件的实现者核实过 ActiveX 控件在理论上是否可以在 Windows 服务场景中工作?

编辑 3 - 在 OP 更新之后:

.emf 是一种矢量文件格式... IIRC GDI+ 用于在当前的 Windows 版本上渲染它....emf 随着时间的推移发生了一些变化,因此较旧的操作系统和/或 Office 版本有时可能会出现渲染问题较新的 .emf 文件...这反过来意味着问题是 Windows 服务中的“缺少桌面”和/或您的 .emf 文件对于生产机器来说“太新”。

【讨论】:

  • 请查看原始问题——我发现没有一个 OpenXML 库可以工作,因为必须使用文件中的 ActiveX 控件。我审查(和测试)的所有库都不能与 ActiveX 对象一起使用,因为按照设计,它们与 XML 一起使用。 ActiveX 对象是这些包中的二进制 blob,而不是 XML。
  • OpenXML SDK 本身无法(据我所知)处理 ActiveX 控件,因此我尝试过的任何包装库(EPPlus、ClosedXml)都不是。
  • 我知道服务器方案不支持互操作。然而,它在 SO 上为数百名其他人“工作”(就互操作“工作”而言)。它也适用于我,除了图像删除。
  • 另外,我试图撤消我的反对票,但最终将其锁定。请编辑以便我删除反对票。
  • @MichaelPaulukonis 这很可能是一个问题,因为 Windows 服务......尤其是。因为 Vista MS 已经对 Windows 服务可以做什么采取了越来越多的安全措施......在 Excel 中处理图像可能以需要 Windows 服务不再拥有的“真实桌面”的方式实现......这反过来意味着您将无法使用 Interop...
【解决方案2】:

您可能需要靠自己,因为正如@Yahia 正确指出的那样,服务器环境不支持 Excel。

您提到的 ActiveX 控件是一个危险信号 - 也许您的某些 ActiveX 控件需要 Excel 在具有配置文件的帐户下运行?

您所能做的就是自己调试,最好通过消除开发和生产环境中不同行为的可能来源来继续。

  • 尝试在两种环境中使用相同的 Office 版本
  • 您是否在开发环境中使用 Cassini? (即在您自己的登录名下运行)如果是这样,也许尝试在没有配置文件的服务帐户下运行 IIS
  • 尝试一一删除 ActiveX 组件,看看其中一个是否有影响 ...等等...

【讨论】:

    【解决方案3】:

    如 cmets 中所述(最终在对问题的编辑中),代码在生产环境中作为服务运行,使用 Local Service 帐户。

    我现在不确定我为什么选择这个帐户——我在研究如何让 Interop 作为服务正确运行时偶然发现的?

    但是,一旦我从 本地服务 帐户切换到 本地系统 帐户(并选中“允许服务与桌面交互”),它就可以工作了。自动。

    1. services.msc
    2. 选择服务
    3. 右键单击,选择“属性”
    4. 选择“登录”标签
    5. 选择“本地系统帐户”并选中“允许服务与桌面交互”

    可能不需要“允许服务与桌面交互”;有关自动化互操作的其他说明表明需要其他桌面设置,但是我进行了安装,其中设置了这些先决条件但未选中此值;应用程序仍然有效...

    【讨论】:

    • 谢谢我遇到了同样的问题,这解决了。令人惊讶的是,这不会引发任何 COM 异常。
    【解决方案4】:

    通过从模板复制带有图片的幻灯片,我在桌面(不是服务)上遇到了同样的问题。 (当在 1 个演示文稿中获得大约 200 个复制粘贴时,但 1300 个具有相同图片的幻灯片工作正常???)

    这个问题很难解决,我认为是硬件相关的,比如 RAM 错误,但不确定

    只有 100 个客户端出现此错误,所以我认为它与硬件有关。

    请注意,我有一个提供 Excel 自动化的网站,它运行良好,即使“它不受 MS blah blah...的支持”!

    您的excel文件似乎已损坏,您必须找到原因。

    【讨论】:

      【解决方案5】:

      (a) 不支持,不要这样做https://support.microsoft.com/en-gb/kb/257757

      (b) 无论如何,如果你必须这样做(并且不能给desktop access to your process, as suggested in the accepted answer),你可以按照this answer的建议将C:\Windows\System32\config\systemprofile中的内容和权限弄乱。

      我必须创建并允许对 DesktopINetCache 文件夹的权限。在Process Monitor 的帮助下检查(并解决)以C:\Windows\System32\config\systemprofile 开头的路径中的失败访问尝试让我摆脱了烦人的问题,并指出INetCache 权限是图像插入失败的原因。

      您只需向C:\Windows\SysWOW64\config\systemprofile\AppData\Local\Microsoft\Windows\INetCacheC:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache(取决于您的系统版本)文件夹添加权限,图像就会显示出来

      【讨论】:

        猜你喜欢
        • 2010-10-15
        • 2017-01-02
        • 2021-09-05
        • 2017-05-12
        • 2011-07-20
        • 1970-01-01
        • 1970-01-01
        • 2018-11-24
        • 1970-01-01
        相关资源
        最近更新 更多