excel - 获取已复制到剪贴板的 Excel 单元格属性
问题描述
我正在尝试将多个单元格中的值复制到一个单元格中。如果我只想组合单元格的值,我会使用类似的东西
Dim str as string = My.Computer.ClipBoard.GetText
oxlapp.ActiveCell.Value = str
然而
在这种情况下,我需要包含 html 标记以创建表格,并且我还想包含粗体、斜体和下划线等格式。因此,我需要知道一些单元格属性,而不仅仅是剪贴板中的文本。
我知道它们应该在那里,因为您当然可以复制/粘贴整个单元格。
到目前为止,我尝试通过使用获取 Excel 单元格
My.Computer.Clipboard.GetData(XlClipboardFormat.xlClipboardFormatTable)
和
My.Computer.Clipboard.GetData(XlClipboardFormat.xlClipboardFormatCSV)
但是在调试时我注意到它们都返回了Nothing
。
有人知道我如何从剪贴板获取所有单元格属性吗?
为了更清楚,我想要这个
变成这样:
如果除了使用剪贴板还有其他方法,我很乐意尝试。
解决方案
您需要使用剪贴板中的另一种格式 - XML Spreadsheet
. 复制的数据包含在具有自己的结构和属性的特殊 XML 中。让我们获取以下工作表的数据:
如您所见,每个单元格都有一些格式。此数据的 XML 如下:
<ss:Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<ss:Styles>
<ss:Style ss:ID="Default" ss:Name="Normal">
<ss:Alignment ss:Vertical="Bottom"/>
<ss:Borders/>
<ss:Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
<ss:Interior/>
<ss:NumberFormat/>
<ss:Protection/>
</ss:Style>
<ss:Style ss:ID="s62">
<ss:Interior ss:Color="#FFFF00" ss:Pattern="Solid"/>
</ss:Style>
<ss:Style ss:ID="s63">
<ss:Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11" ss:Color="#000000" ss:Bold="1"/>
</ss:Style>
<ss:Style ss:ID="s64">
<ss:Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11" ss:Color="#0000FF"/>
</ss:Style>
<ss:Style ss:ID="s65">
<ss:Font ss:FontName="Calibri" x:CharSet="204" x:Family="Swiss" ss:Size="11" ss:Color="#000000" ss:Italic="1"/>
</ss:Style>
</ss:Styles>
<ss:Worksheet ss:Name="Sheet1">
<ss:Table ss:ExpandedColumnCount="2" ss:ExpandedRowCount="2" ss:DefaultRowHeight="15">
<ss:Row>
<ss:Cell ss:StyleID="s62">
<ss:Data ss:Type="String">A</ss:Data>
</ss:Cell>
<ss:Cell ss:StyleID="s63">
<ss:Data ss:Type="String">1</ss:Data>
</ss:Cell>
</ss:Row>
<ss:Row>
<ss:Cell ss:StyleID="s64">
<ss:Data ss:Type="String">B</ss:Data>
</ss:Cell>
<ss:Cell ss:StyleID="s65">
<ss:Data ss:Type="String">2</ss:Data>
</ss:Cell>
</ss:Row>
</ss:Table>
</ss:Worksheet>
</ss:Workbook>
如您所见,您拥有有关相应样式格式的所有信息。例如,单元格中的值A
具有A1
样式s62
(StyleID
属性) - 您可以在节点中找到Style
具有此编号的适当Styles
节点。此 XML 中的行和列的结构是隐含的 - 即您不会看到行和列的索引 - 您需要自己计算它们。例如,第一个节点中的第二个Cell
节点Row
是第一行,第二列。
以下代码生成上图中的数据并检索适当的元素进行操作。
注意事项 1.如果仔细观察,该Workbook
节点有两个 urn:schemas-microsoft-com:office:spreadsheet
命名空间:第一个是 default ,第二个是带有 prefix ss
。请记住 - 你总是需要使用ss
前缀!
注意事项 2.这种方法有一个缺点- 它不理解隐藏的行(手动或通过自动过滤器)和列!它也包括隐藏的行/列!
Imports <xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
Imports <xmlns:x="urn:schemas-microsoft-com:office:excel">
Sub GetCellsWithFormat()
'// Create new Excel app
Dim xlApp = New Excel.Application With {.Visible = True}
Dim book = xlApp.Workbooks.Add()
Dim sheet = DirectCast(book.Sheets(1), Excel.Worksheet)
'// Apply some formatting
With sheet
.Range("A1").Interior.Color = Excel.XlRgbColor.rgbYellow
.Range("B1").Font.Bold = True
.Range("A2").Font.Color = Excel.XlRgbColor.rgbBlue
.Range("B2").Font.Italic = True
'// Add some values
Dim arr = Array.CreateInstance(GetType(String), {2, 2}, {1, 1})
arr(1, 1) = "A" : arr(1, 2) = "1"
arr(2, 1) = "B" : arr(2, 2) = "2"
With .Range("A1:B2")
.Value = arr
.Copy() '//Copy cells to clipboard
End With
Dim xml As XElement
Using xml_stream = DirectCast(Clipboard.GetData("XML Spreadsheet"), Stream)
'// Get rid of last character (new line) to avoid parsing error
xml_stream.SetLength(xml_stream.Length - 1)
xml = XElement.Load(xml_stream)
End Using
'// Get any element you need
Dim styles = xml.<ss:Styles>(0)
Dim table = xml.<ss:Worksheet>.<ss:Table>(0)
Dim rows = table.<ss:Row>
'// Do something with this data
End With
End Sub
更新
事实上,你不需要使用剪贴板来获取这个 XML - 你只需要使用属性xlRangeValueXMLSpreadsheet
的值Value
:
With sheet
'// Same code...
With .Range("A1:B2")
.Value = arr
'.Copy() '//No need to copy!
End With
Dim xml_string = CStr(.Range("A1:B2").Value(Excel.XlRangeValueDataType.xlRangeValueXMLSpreadsheet))
'// Again, exclude last character
Dim xml = XElement.Parse(xml_string.Substring(0, xml_string.Length - 1))
'// Get any element you need
Dim styles = xml.<ss:Styles>(0)
Dim table = xml.<ss:Worksheet>.<ss:Table>(0)
Dim rows = table.<ss:Row>
'// Do something with this data
End With
推荐阅读
- javascript - 有没有办法通过 chrome 扩展将文件直接保存到本地硬盘
- asp.net-core - 传入错误的枚举值时,如何在 ASP.NET Core 中获取自定义 ModelState 错误消息?
- angular - 用Angular 8函数替换链式过滤器/订单管道
- python - 如何将 oseti 中的情绪值附加到 pandas 数据框?
- python - EmptyDataError:在字典中加载多个文件时,没有要从文件中解析的列
- c++ - Using range-v3 to read comma separated list of numbers
- sql-server - 从日期列表中单独选择日期
- visual-studio-code - 在 VS 代码中读取 cosmosDB 文件时出现问题,原因是:在文件名中
- stored-procedures - 雪花存储过程与独立 sql
- c# - 使用当前 Serilog ILogger 实例将消息格式化为字符串(但不打印)