获取已复制到剪贴板的Excel单元格属性

时间:2019-07-03 17:10:59

标签: excel vb.net

我正在尝试将多个单元格中的值复制到一个单元格中。如果我只想合并单元格的值,则可以使用

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

有人知道我如何从剪贴板中获取所有单元格属性吗?

为了更清楚一点,我想要这个

enter image description here

要变成这个:

enter image description here

如果使用剪贴板以外的其他方法,我很乐意尝试。

2 个答案:

答案 0 :(得分:1)

您需要使用剪贴板中的另一种格式-XML Spreadsheet。复制的数据包含在具有其自身结构和属性的特殊XML中。让我们获取以下工作表的数据:

IMG1

如您所见,每个单元格都有一些格式。此数据的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具有样式s62StyleID属性)-您可以在{{1 }}节点。此XML中的行和列结构是隐式的-也就是说,您不会看到行和列的索引-您需要自己计算它们。例如,第一个Style节点中的第二个Styles节点是第一行第二列

以下代码在上图中生成数据,并检索要操作的适当元素。

注意事项1。如果仔细观察,Cell节点具有两个 Row命名空间:第一个是默认名称,第二个是第二个是前缀Workbook。请记住-您始终需要使用urn:schemas-microsoft-com:office:spreadsheet前缀!

请注意2。。此方法有一个缺点-它无法理解隐藏的行(手动或通过自动过滤器)和列!它也包括隐藏的行/列!

ss

更新

实际上,您不需要使用剪贴板来获取此XML-您只需要使用ss属性的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 值:

xlRangeValueXMLSpreadsheet

答案 1 :(得分:0)

当我想允许从Excel复制到我编写的自定义Windows应用程序中的数据时,我使用GetText()而不是GetData()。

将ClipboardText设为字符串=什么都没有

   ClipboardText = My.Computer.Clipboard.GetText()

如果是从Excel复制到剪贴板的多个单元格,则根据选择,可以用vbTab和vbCrLf分隔它们。