提问人:Rand Random 提问时间:3/6/2020 最后编辑:Rand Random 更新时间:3/12/2020 访问量:2177
将 OLE 对象插入 MS Word 文档并保持基础格式 WMF 不变
Insert OLE Object into MS Word Document and keep the underlying format WMF intact
问:
我正在尝试在 C# Word 互操作 (NetOffice) 中复制以下方法
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
我之所以说“复制”,是因为我不想实际使用该方法,因为我需要一次性更新许多类型,并且不喜欢依靠复制和粘贴与 excel 进行通信。PasteSpecial
field
link
我已经有以下代码,它基本上可以满足我的需求,但有一些我无法克服的问题。
Selection.InlineShapes.AddOLEObject ("Excel.Sheet.12", fileName + $"!{label}", true)
此方法失败,并显示错误消息
Word 无法创建指向指定对象的链接。请将对象直接插入到您的文件中,而无需创建链接
只有当且仅当我使用带有标签的网络驱动器或 unc 路径时,我才会收到此错误消息。 例如。
T:\TestFile.xlsx!Sheet1!TestRange
T:\TestFile.xlsx!Sheet1!R1C1:R2C2
//notice that T is a network drive and not a local drive
\\TestShare\TestFile.xlsx!Sheet1!TestRange
\\TestShare\TestFile.xlsx!Sheet1!R1C1:R2C2
如果我不使用标签 例如。
T:\TestFile.xlsx
T:\TestFile.xlsx
//notice that T is a network drive and not a local drive
\\TestShare\TestFile.xlsx
\\TestShare\TestFile.xlsx
或本地驱动器,例如。C:(带或不带标签)
C:\TestFile.xlsx
C:\TestFile.xlsx
C:\TestFile.xlsx!Sheet1!TestRange
C:\TestFile.xlsx!Sheet1!R1C1:R2C2
一切正常。
因此,只有组合网络驱动器或 unc + 标签才会产生该错误消息。
我想,好吧,没问题,我已经知道如何更改生成的路径和标签,并编写了以下代码以在第二步中包含标签。field
var inlineShape = Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", fileName, true);
field = inlineShape.Field;
if (!string.IsNullOrEmpty(label))
{
var fieldCode = field.Code.Text;
//replace the produced empty label "" with the label I desire eg. "Sheet1!R1C1:R2C2"
fieldCode = fieldCode.Replace(" \"\" ", $" \"{label}\"");
//write the updated fieldcode back to the field
field.Code.Text = fieldCode;
//update the field
field.Update();
}
但是这个解决方案将图像的基础格式从 WMF(Windows 元文件)更改为 EMF(增强元文件),但我需要它以 WMF 格式存储,因为无法正确呈现 EMF。Office 2010
为了获取基础文件,我将 my 重命名为 to 并提取它以查看目录。docx
zip
word\media
PasteSpecial
不会抛出该错误,并生成所需的 WMF 格式,但我似乎无法 100% 复制 .PasteSpecial
正如我所指出的,我不想有 or ,因为这些是在字体周围模糊的情况下生成的,所以最好的结果是 .png
bmp
wmf
Office 2010
对于及更高级别的代码,我使用以下代码从一开始就正确,并且不会遇到有关网络驱动器/ unc +标签错误的问题。Office 2013
emf
var field = range.Fields.Add(range, WdEnums.WdFieldType.wdFieldLink);
field.LinkFormat.SourceFullName = fileName + $"!{label}";
编辑:
这是我试图解决的主要问题的屏幕截图,因为我提醒一下,这就是它的外观,而且看起来都不错:Office 2010
Office 2013
对于两者,我都使用粘贴特殊 https://support.office.com/en-us/article/paste-special-e03db6c7-8295-4529-957d-16ac8a778719
word文档中的第一个表格生成一个EMF文件,同时使用粘贴特殊格式“图片(增强的图元文件)”,宏录制生成以下代码:
Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, _
Placement:=wdInLine, DisplayAsIcon:=False
word 文档中的第二个表生成一个 WMF 文件,同时使用粘贴特殊格式“图片(Windows 元文件)”,宏录制生成以下代码:
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
在右侧,您可以看到我复制以粘贴到左侧 word 文档中的 excel 文件。
正如你清楚地看到的,渲染/绘制 WMF 文件(word 文档中的第二个表)要好得多,所以这将是我想要的输出,但正如我提到的,我一直在努力复制和保持渲染/绘制更好的文件。Office 2010
PasteSpecial
WMF
编辑2:
我录制了我的屏幕以显示错误,请原谅我的环境是德语。https://i.stack.imgur.com/sQNBo.jpg
我使用的代码是这样的:
Sub NetworkAndLabel()
'this will fail
Dim fileName As String
Dim label As String
'T is a mapped drive for the share \\NAS1\Ablage
fileName = "T:\rfa\TestFile.xlsx"
'label is in german, in english it would be Sheet1!R1C1:R1C2
label = "Tabelle1!Z1S1:Z2S2"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName & "!" & label, True
End Sub
Sub Network()
'this will run successfully
Dim fileName As String
Dim label As String
'T is a mapped drive for the share \\NAS1\Ablage
fileName = "T:\rfa\TestFile.xlsx"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName, True
End Sub
Sub LocalAndLabel()
'this will run successfully
Dim fileName As String
Dim label As String
'E is a local drive (second partition, not a seperate drive)
'up till now, I only tested with C and wanted to see if a simple second partition works or not
fileName = "E:\rfa\TestFile.xlsx"
'label is in german, in english it would be Sheet1!R1C1:R1C2
label = "Tabelle1!Z1S1:Z2S2"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName & "!" & label, True
End Sub
Sub Local_()
'this will run successfully
Dim fileName As String
Dim label As String
'E is a local drive (second partition, not a seperate drive)
'up till now, I only tested with C and wanted to see if a simple second partition works or not
fileName = "E:\rfa\TestFile.xlsx"
Selection.InlineShapes.AddOLEObject "Excel.Sheet.12", fileName, True
End Sub
我在 excel 文件中写了“UsedRange”,以显示 word 中的不同输出,如果标签正在使用或未使用,如果我不指定标签,它会使用第一张纸的标签。C5
UsedRange
仅供参考,我编写了简单的代码,以证明它与它无关,并且可以在没有任何特殊之处的情况下进行自然复制。最后,解决方案(如果有)将包含在我的应用程序中。vba
C#
C#
编辑3:
澄清一下,如果有人知道一种使文件更好地渲染/绘制的方法,那对于我的问题来说也是一个有效的解决方案,因为归根结底,我只想在我的 word 文档中有一个看起来不错的链接 excel 文件。我真的不在乎是否或,我只是试图使用它,因为它看起来更好,并且有我描述的问题,告诉要保持格式。Office 2010
EMF
EMF
WMF
WMF
Office 2010
WMF
因为我知道,克服错误消息的唯一方法是操作 ,如上所示,但是一旦我调用文件就会被替换为 ,并且我最终会得到文件的糟糕渲染/绘制。Field
field.Update()
WMF
EMF
EMF
编辑4:
根据要求,我查看了文档的内部结构并查看了差异。实际差异基本上是 0,只有应该无关紧要的东西,比如修订号、字符数和类似的东西。
但是我注意到以下内容,即使这段代码
Selection.PasteSpecial Link:=True, DataType:=wdPasteMetafilePicture, _
Placement:=wdInLine, DisplayAsIcon:=False
生成一个文件,我可以通过查看文件夹并查看生成的文件或查看具有以下条目的文件来查看该文件WMF
word\media
image1.wmf
word\_rels\document.xml.rels
<Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.wmf"/>
OLE 对象的实际值如下:XML
word\document.xml
<o:OLEObject Type="Link" ProgID="Excel.Sheet.12" ShapeID="_x0000_i1025" DrawAspect="Content" r:id="rId8" UpdateMode="Always"><o:LinkType>EnhancedMetaFile</o:LinkType><o:LockedField>false</o:LockedField></o:OLEObject>
如您所见,它被定义为 (EMF)。LinkType
EnhancedMetaFile
由于 OLE 对象是这样定义的,我尝试了一个简单的调用是否会触发从 到 的更改,可悲的是,情况就是这样,所以即使我不修改 的代码,像这样的简单调用field.Update
WMF
EMF
field
Selection.InlineShapes(1).Field.Update
由于OLE对象只是简单地这样定义,因此已经触发了从到的转换,因此转换也可以在没有任何自定义代码的情况下实现,只需选择内联形状并点击或右键单击并选择(从我的德语环境翻译)WMF
EMF
F9
Update Links
请注意,无论出于何种原因,此代码
Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", "E:\rfa\TestFile.xlsx", True).Field.Update
不会触发转换,但如果你保存word文档并再次打开它,那么你可以调用触发转换。field.Update
因此,要一次性进行转换,而无需保存/关闭 word 文档,您至少需要调用它
With Selection.InlineShapes.AddOLEObject("Excel.Sheet.12", "E:\rfa\TestFile.xlsx!Tabelle1!Z1S1:Z2S2", True).Field
.Code.Text = Replace(.Code.Text, "Z1S1:Z2S2", "Z2S2:Z3S3")
.Update
End With
答: 暂无答案
评论
Word is unable to create a link to the object you specified...
\\TestShare\TestFile.xlsx
LocalAndLabel