首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OpenXML添加注释和线程注释

OpenXML添加注释和线程注释
EN

Stack Overflow用户
提问于 2022-04-06 15:03:08
回答 2查看 120关注 0票数 0

我发布这篇文章是为了帮助其他可能正在经历困境的人,我试图使用DocumentFormat.OpenXML库使用VB.Net向excel电子表格中添加简单的注释或线程注释。

我补充了我自己的答案。

EN

回答 2

Stack Overflow用户

发布于 2022-04-06 15:09:28

代码语言:javascript
运行
复制
Imports System.Text
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Imports System.Runtime.CompilerServices
Imports System.Xml
Imports System.IO
Imports System.Text.RegularExpressions
Imports DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments

Public Class ExcelDocInfo
    Public Property WBPart As WorkbookPart = Nothing
    Public Property WSPart As WorksheetPart = Nothing
    Public Property SData As SheetData = Nothing
End Class

Public Class CellReferenceIndexes
    Public ColumnIndex As Integer? = Nothing
    Public RowIndex As Integer? = Nothing

    Public Sub New()

    End Sub
End Class

Public Class OpenXML
    Public Shared Function GetThreadedCommentVMLShapeXML(CellReference As String, CommentCount As Integer)
        Dim commentVmlXml As String = String.Empty

        commentVmlXml = <![CDATA[
<v:shape id="[ShapeID]" type="#_x0000_t202" style='position:absolute; margin-left:59.25pt;margin-top:1.5pt;width:108pt;height:59.25pt;z-index:1; visibility:hidden' fillcolor="infoBackground [80]" strokecolor="none [81]" o:insetmode="auto">
    <v:fill color2="infoBackground [80]"/>
    <v:shadow color="none [81]" obscured="t"/>
    <v:path o:connecttype="none"/>
    <v:textbox style='mso-direction-alt:auto'>
        <div style='text-align:left'></div>
    </v:textbox>
    <x:ClientData ObjectType="Note">
        <x:MoveWithCells/>
        <x:SizeWithCells/>
        <x:Anchor>[CoordinatesForVMLCommentShape]</x:Anchor>
        <x:AutoFill>False</x:AutoFill>
        <x:Row>[RowIndex]</x:Row>
        <x:Column>[ColumnIndex]</x:Column>
    </x:ClientData>
</v:shape>
]]>.Value.Trim()
        Dim ShapeId As String = "_x0000_s" & (1109 + CommentCount + 1).ToString()
        commentVmlXml = commentVmlXml.Replace("[ShapeID]", ShapeId)
        commentVmlXml = commentVmlXml.Replace("[CoordinatesForVMLCommentShape]", GetAnchorCoordinatesForVMLCommentShape(CellReference))

        commentVmlXml = commentVmlXml.Replace("[RowIndex]", (GetIndexesFromCellReference(CellReference).RowIndex - 1).ToString())
        commentVmlXml = commentVmlXml.Replace("[ColumnIndex]", (GetIndexesFromCellReference(CellReference).ColumnIndex - 1).ToString())

        Return commentVmlXml
    End Function

    Public Shared Function GetNoteVMLShapeXML(CellReference As String, CommentCount As Integer)
        Dim commentVmlXml As String = String.Empty

        commentVmlXml = <![CDATA[
<v:shape id="[ShapeID]" type="#_x0000_t202" style='position:absolute; margin-left:59.25pt; margin-top:1.5pt; width:108pt; height:59.25pt; z-index:1; visibility:hidden' fillcolor="#ffffe1" o:insetmode="auto">
    <v:fill color2="#ffffe1" />
    <v:shadow on="t" color="black" obscured="t" />
    <v:path o:connecttype="none" />
    <v:textbox style='mso-fit-shape-to-text:true'>
        <div style='text-align:left'></div>
    </v:textbox>
    <x:ClientData ObjectType="Note">
        <x:MoveWithCells />
        <x:SizeWithCells />
        <x:Anchor>[CoordinatesForVMLCommentShape]</x:Anchor>
        <x:AutoFill>False</x:AutoFill>
        <x:Row>[RowIndex]</x:Row>
        <x:Column>[ColumnIndex]</x:Column>
    </x:ClientData>
    </v:shape>
]]>.Value.Trim()
        Dim ShapeId As String = "_x0000_s" & (1109 + CommentCount + 1).ToString()
        commentVmlXml = commentVmlXml.Replace("[ShapeID]", ShapeId)
        commentVmlXml = commentVmlXml.Replace("[CoordinatesForVMLCommentShape]", GetAnchorCoordinatesForVMLCommentShape(CellReference))

        commentVmlXml = commentVmlXml.Replace("[RowIndex]", (GetIndexesFromCellReference(CellReference).RowIndex - 1).ToString())
        commentVmlXml = commentVmlXml.Replace("[ColumnIndex]", (GetIndexesFromCellReference(CellReference).ColumnIndex - 1).ToString())

        Return commentVmlXml
    End Function

    Public Shared Function GetAnchorCoordinatesForVMLCommentShape(CellReference As String) As String
        Dim coordinates As String = String.Empty

        Dim startingRow As Integer = 0
        Dim startingColumn As Integer = GetIndexesFromCellReference(CellReference).ColumnIndex - 1

        'From upper right coordinate of a rectangle
        '[0] Left column
        '[1] Left column offset
        '[2] Left row
        '[3] Left row offset
        'To bottom right coordinate of a rectangle
        '[4] Right column
        '[5] Right column offset
        '[6] Right row
        '[7] Right row offset
        Dim coordList As List(Of Integer) = {0, 0, 0, 0, 0, 0, 0, 0}.ToList()

        If Integer.TryParse(GetIndexesFromCellReference(CellReference).RowIndex, startingRow) Then
            startingRow -= 1

            coordList(0) = startingColumn + 1
            coordList(1) = 15
            coordList(2) = startingRow
            coordList(4) = startingColumn + 3
            coordList(5) = 15
            coordList(6) = startingRow + 3

            If startingRow = 0 Then
                coordList(3) = 2
                coordList(7) = 16
            Else
                coordList(3) = 10
                coordList(7) = 4
            End If

            coordinates = String.Join(",", coordList.ConvertAll(Of String)(Function(X) X.ToString()).ToArray())
        End If

        Return coordinates
    End Function

    Public Shared Function GetIndexesFromCellReference(CellReference As String) As CellReferenceIndexes
        Dim CellReferenceInfo As New CellReferenceIndexes

        Dim ColRef As String = ""
        For Each C As Char In CellReference
            If Not IsNumeric(C) Then
                ColRef &= C
            Else
                Exit For
            End If
        Next
        ColRef = ColRef.ToUpper()

        CellReferenceInfo.RowIndex = Strings.Right(CellReference, CellReference.Length - ColRef.Length)

        Dim ColIndex As Integer = 0

        For Idx As Integer = 0 To ColRef.Length - 1
            ColIndex *= 26
            Dim charA As Integer = Asc("A")
            Dim charColLetter As Integer = Asc(ColRef(Idx))
            ColIndex += (charColLetter - charA) + 1
        Next

        CellReferenceInfo.ColumnIndex = ColIndex

        Return CellReferenceInfo
    End Function

    Public Shared Sub AddNote(DocInfo As ExcelDocInfo, XCell As Cell, XAuthor As String, Comment As String, Optional XFontName As String = "Tahoma", Optional FontSize As Double = 11, Optional FontBold As Boolean = False, Optional FontItalic As Boolean = False, Optional TextColor As System.Drawing.Color = Nothing, Optional HighlightColor As System.Drawing.Color = Nothing)
        If DocInfo Is Nothing Then
            Exit Sub
        End If

        If XCell Is Nothing Then
            Exit Sub
        End If

        If String.IsNullOrEmpty(XAuthor) Then
            Exit Sub
        End If

        If String.IsNullOrEmpty(Comment) Then
            Exit Sub
        End If

        If TextColor = Nothing Then TextColor = System.Drawing.Color.Black

        Dim CommentsPart As WorksheetCommentsPart = Nothing
        If DocInfo.WSPart.WorksheetCommentsPart Is Nothing Then
            CommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetCommentsPart)
        Else
            CommentsPart = DocInfo.WSPart.WorksheetCommentsPart()
        End If

        Dim XComments As Comments = CommentsPart.Comments
        If XComments Is Nothing Then
            XComments = New Comments() With {.MCAttributes = New MarkupCompatibilityAttributes() With {.Ignorable = "xr"}}
            XComments.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006")
            XComments.AddNamespaceDeclaration("xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision")

            CommentsPart.Comments = XComments
        End If

        Dim XAuthors As Authors = XComments.GetFirstChild(Of Authors)
        If XAuthors Is Nothing Then
            XAuthors = New Authors()
            XComments.Append(XAuthors)
        End If

        Dim XLAuthor As Author = (From A As Author In XAuthors.ToList() Where A.Text = XAuthor).FirstOrDefault()
        If XLAuthor Is Nothing Then
            XLAuthor = New Author() With {.Text = XAuthor}
            XAuthors.Append(XLAuthor)
        End If

        Dim AuthorID As UInt32 = Convert.ToUInt32(XAuthors.AsEnumerable.ToList().IndexOf(XLAuthor))

        Dim CommList As CommentList = XComments.GetFirstChild(Of CommentList)
        If CommList Is Nothing Then
            CommList = New CommentList()
            XComments.Append(CommList)
        End If

        Dim XComment As Comment = XComments.CommentList.AppendChild(Of Comment)(New Spreadsheet.Comment() With {
                                                                                    .AuthorID = New UInt32Value(AuthorID),
                                                                                    .Reference = XCell.CellReference,
                                                                                    .ShapeId = New UInt32Value(Convert.ToUInt32(0))
                                                                                })
        Dim XCommentText As New CommentText()

        Dim XRun As New Run()
        Dim XRunProperties As New RunProperties()
        Dim XFontSize As New FontSize() With {.Val = New DoubleValue(Convert.ToDouble(FontSize))}
        Dim XColor As New Color() With {.Rgb = New HexBinaryValue With {.Value = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(TextColor.ToArgb())).Replace("#", "")}}
        Dim XFillColor As Color = Nothing
        If HighlightColor <> Nothing Then
            XFillColor = New Color() With {.Rgb = New HexBinaryValue With {.Value = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(HighlightColor.ToArgb())).Replace("#", "")}}
        End If
        Dim XRunFont As New RunFont With {.Val = New StringValue(XFontName)}
        Dim XRunBold As New Bold() With {.Val = New BooleanValue(FontBold)}
        Dim XRunItalic As New Italic() With {.Val = New BooleanValue(FontItalic)}
        Dim xRunPropertyCharSet As New RunPropertyCharSet() With {.Val = New Int32Value(Convert.ToInt32(1))}

        XRunProperties.Append(XFontSize)
        XRunProperties.Append(XColor)
        If XFillColor IsNot Nothing Then
            XRunProperties.Append(XFillColor)
        End If
        XRunProperties.Append(XRunFont)
        XRunProperties.Append(XRunBold)
        XRunProperties.Append(XRunItalic)
        XRunProperties.Append(xRunPropertyCharSet)

        Dim XText As New Text() With {.Space = SpaceProcessingModeValues.Preserve, .Text = Comment}

        XRun.Append(XRunProperties)
        XRun.Append(XText)

        XCommentText.Append(XRun)
        XComment.Append(XCommentText)

        Dim DrawingPartList As List(Of VmlDrawingPart) = DocInfo.WSPart.VmlDrawingParts.ToList()

        Dim CommentCount As Integer = 0

        Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
        Dim Writer As XmlTextWriter = Nothing
        Dim DrawingPartStream As Stream = Nothing
        Dim SR As StreamReader = Nothing
        If DrawingPart Is Nothing Then
            DrawingPart = DocInfo.WSPart.AddNewPart(Of VmlDrawingPart)()
            DrawingPartStream = DrawingPart.GetStream(IO.FileMode.Create)
            SR = New StreamReader(DrawingPartStream)
            Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)

            Dim XMLText As String = <![CDATA[
    <xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o=\"urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
    <o:shapelayout v:ext="edit">
        <o:idmap v:ext="edit" data="1" />
    </o:shapelayout>
    <v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe">
        <v:stroke joinstyle="miter"/>
        <v:path gradientshapeok="t" o:connecttype="rect" />
    </v:shapetype>
    ]]>.Value.Trim()

            Writer.WriteRaw(XMLText)
            Writer.Flush()

            DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing")
            DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main")

            Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart)
            Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID}
            DocInfo.WSPart.Worksheet.Append(XLegacyDrawing)
        Else
            DrawingPartStream = DrawingPart.GetStream()
            SR = New StreamReader(DrawingPartStream)
            Dim ReadText As String = SR.ReadToEnd()

            Dim MatchColl As MatchCollection = Nothing
            Dim MatchPattern As New Regex("\<v:shape ")
            MatchColl = MatchPattern.Matches(ReadText)
            CommentCount = MatchColl.Count
            MatchColl = Nothing
            MatchPattern = Nothing

            Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
        End If

        Dim commentsVmlXml As String = String.Empty

        commentsVmlXml = GetNoteVMLShapeXML(XCell.CellReference.Value, CommentCount)

        Writer.WriteRaw(commentsVmlXml)
        Writer.Flush()
        Writer.Close()
        Writer.Dispose()
        Writer = Nothing

        SR.Close()
        SR.Dispose()

        DrawingPartStream.Close()
        DrawingPartStream.Dispose()
    End Sub

    Public Shared Sub AddThreadedComment(DocInfo As ExcelDocInfo, XCell As Cell, XAuthor As String, Comment As String)
        If DocInfo Is Nothing Then
            Exit Sub
        End If

        If XCell Is Nothing Then
            Exit Sub
        End If

        If String.IsNullOrEmpty(XAuthor) Then
            Exit Sub
        End If

        If String.IsNullOrEmpty(Comment) Then
            Exit Sub
        End If

        Dim CommentsPart As WorksheetCommentsPart = Nothing
        If DocInfo.WSPart.WorksheetCommentsPart Is Nothing Then
            CommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetCommentsPart)
        Else
            CommentsPart = DocInfo.WSPart.WorksheetCommentsPart()
        End If

        Dim XComments As Comments = CommentsPart.Comments
        If XComments Is Nothing Then
            XComments = New Comments() With {.MCAttributes = New MarkupCompatibilityAttributes() With {.Ignorable = "xr"}}
            XComments.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006")
            XComments.AddNamespaceDeclaration("xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision")

            CommentsPart.Comments = XComments
        End If

        Dim PersPart As WorkbookPersonPart = DocInfo.WBPart.GetPartsOfType(Of WorkbookPersonPart).FirstOrDefault()
        If PersPart Is Nothing Then
            PersPart = DocInfo.WBPart.AddNewPart(Of WorkbookPersonPart)
        End If

        Dim PersList As PersonList = PersPart.PersonList
        If PersList Is Nothing Then
            PersList = New PersonList
            PersList.AddNamespaceDeclaration("x", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
            PersPart.PersonList = PersList
        End If

        Dim Pers As Person = (From P As Person In PersList.AsEnumerable() Where P.DisplayName.Value = XAuthor Select P).FirstOrDefault()
        If Pers Is Nothing Then
            Pers = New Person() With {.DisplayName = New StringValue(XAuthor), .Id = New StringValue("{" & Guid.NewGuid().ToString().ToUpper() & "}"), .UserId = New StringValue(XAuthor), .ProviderId = New StringValue("None")}
            PersList.Append(Pers)
        End If

        Dim XAuthors As Authors = XComments.GetFirstChild(Of Authors)
        If XAuthors Is Nothing Then
            XAuthors = New Authors()
            XComments.Append(XAuthors)
        End If

        Dim AuthorGUID As String = "{" & Guid.NewGuid().ToString() & "}"
        Dim XLAuthor As Author = New Author() With {.Text = "tc=" & AuthorGUID}
        XAuthors.Append(XLAuthor)

        Dim WSThreadedCommentsPart As WorksheetThreadedCommentsPart = DocInfo.WSPart.WorksheetThreadedCommentsParts.FirstOrDefault()
        If WSThreadedCommentsPart Is Nothing Then
            WSThreadedCommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetThreadedCommentsPart)
        End If

        Dim XThreadedComments As ThreadedComments = WSThreadedCommentsPart.ThreadedComments
        If XThreadedComments Is Nothing Then
            XThreadedComments = New ThreadedComments()
            WSThreadedCommentsPart.ThreadedComments = XThreadedComments
        End If

        Dim XThreadedComment As ThreadedComment = New ThreadedComment() With {.Ref = New StringValue(XCell.CellReference), .DT = New DateTimeValue(Now().ToUniversalTime()), .PersonId = Pers.Id, .Id = New StringValue(AuthorGUID)}
        Dim XThreadedCommentText As New ThreadedCommentText(Comment)
        XThreadedComment.Append(XThreadedCommentText)
        XThreadedComments.Append(XThreadedComment)

        Dim AuthorID As UInt32 = Convert.ToUInt32(XAuthors.ToList().IndexOf(XLAuthor))

        Dim CommList As CommentList = XComments.GetFirstChild(Of CommentList)
        If CommList Is Nothing Then
            CommList = New CommentList()
            XComments.Append(CommList)
        End If

        Dim XComment As Comment = XComments.CommentList.AppendChild(Of Comment)(New Spreadsheet.Comment() With {
                                                                                    .AuthorID = New UInt32Value(AuthorID),
                                                                                    .Reference = XCell.CellReference,
                                                                                    .ShapeId = New UInt32Value(Convert.ToUInt32(0))
                                                                                })
        XComment.SetAttribute(New OpenXmlAttribute("uid", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision", Pers.Id.Value))

        Dim Prepend As String = "[Threaded comment]

    Your version of Excel allows you to read this threaded comment; however, any edits to it will get removed if the file is opened in a newer version of Excel. Learn more: https://go.microsoft.com/fwlink/?linkid=870924

    Comment:
        "

        Dim XCommentText As New CommentText()
        Dim XText As New Text() With {.Text = Prepend & Comment}
        XCommentText.Append(XText)
        XComment.Append(XCommentText)

        Dim DrawingPartList As List(Of VmlDrawingPart) = DocInfo.WSPart.VmlDrawingParts.ToList()

        Dim CommentCount As Integer = 0

        Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
        Dim Writer As XmlTextWriter = Nothing
        Dim DrawingPartStream As Stream = Nothing
        Dim SR As StreamReader = Nothing
        If DrawingPart Is Nothing Then
            DrawingPart = DocInfo.WSPart.AddNewPart(Of VmlDrawingPart)()
            DrawingPartStream = DrawingPart.GetStream(IO.FileMode.Create)
            SR = New StreamReader(DrawingPartStream)
            Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
            Dim XMLText As String = <![CDATA[
    <xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o=\"urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
    <o:shapelayout v:ext="edit">
        <o:idmap v:ext="edit" data="1" />
    </o:shapelayout>
    <v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe">
        <v:stroke joinstyle="miter"/>
        <v:path gradientshapeok="t" o:connecttype="rect" />
    </v:shapetype>
    ]]>.Value.Trim()

            Writer.WriteRaw(XMLText)
            Writer.Flush()

            DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing")
            DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main")

            Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart)
            Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID}
            DocInfo.WSPart.Worksheet.Append(XLegacyDrawing)
        Else
            DrawingPartStream = DrawingPart.GetStream()
            SR = New StreamReader(DrawingPartStream)
            Dim ReadText As String = SR.ReadToEnd()

            Dim MatchColl As MatchCollection = Nothing
            Dim MatchPattern As New Regex("\<v:shape ")
            MatchColl = MatchPattern.Matches(ReadText)
            CommentCount = MatchColl.Count
            MatchColl = Nothing
            MatchPattern = Nothing

            Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
        End If

        Dim commentsVmlXml As String = String.Empty

        commentsVmlXml = GetThreadedCommentVMLShapeXML(XCell.CellReference.Value, CommentCount)

        Writer.WriteRaw(commentsVmlXml)
        Writer.Flush()
        Writer.Close()
        Writer.Dispose()
        Writer = Nothing

        SR.Close()
        SR.Dispose()

        DrawingPartStream.Close()
        DrawingPartStream.Dispose()
    End Sub

    Public Shared Sub FinalizeComments(DocInfo As ExcelDocInfo)
        Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
        If DrawingPart IsNot Nothing Then
            Using DrawingPartStream As Stream = DrawingPart.GetStream()
                Using SR As StreamReader = New StreamReader(DrawingPartStream)
                    Dim ReadText As String = SR.ReadToEnd()
                    If Not ReadText.ToLower().EndsWith("</xml>") Then
                        Using Writer As XmlTextWriter = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
                            Writer.WriteRaw("</xml>")
                            Writer.Flush()
                            Writer.Close()
                        End Using
                    End If

                    SR.Close()
                End Using
                DrawingPartStream.Close()
            End Using
        End If
    End Sub

    Public Shared Function GetCell(ExcelRow As Row, ColumnNumber As Integer) As Cell
        Dim WSCell As Cell = Nothing
        If (From C As Cell In ExcelRow.Elements(Of Cell) Where C.CellReference.Value = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()).Count > 0 Then
            WSCell = (From C As Cell In ExcelRow.Elements(Of Cell) Where C.CellReference.Value = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()).FirstOrDefault()
        Else
            WSCell = New Cell() With {.CellReference = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()}
            ExcelRow.InsertAt(Of Cell)(WSCell, ExcelRow.Elements(Of Cell).Count)
        End If

        Return WSCell
    End Function

    Public Shared Function GetRow(SData As SheetData, RowNumber As Integer) As Row
        Dim R As Row = Nothing

        Dim RIdx As UInt32Value = Convert.ToUInt32(RowNumber)
        If SData.Elements(Of Row).Count > 0 Then
            R = (From ERow As Row In SData.Elements(Of Row) Where ERow.RowIndex = RIdx).FirstOrDefault()
        End If

        If R Is Nothing Then
            R = New Row() With {.RowIndex = RIdx}
            SData.Append(R)
        End If

        Return R
    End Function
End Class

Public Class TestCase
    Public Sub RunTest()
        'This sample does not dive into the creation of the spreadsheet. This example focuses strictly on notes and threaded comments.
        'In a production example, there would be another sub in the OpenXML class that would populate this ExcelDocInfo object.
        'Note that this code will fail as the objects within the DocInfo object currently have no reference to actual objects
        Dim DocInfo As New ExcelDocInfo

        Dim RowIdx As Integer = 1
        Dim ColIdx As Integer = 1

        Dim XRow As Row = OpenXML.GetRow(DocInfo.SData, RowIdx)
        Dim XCell As Cell = OpenXML.GetCell(XRow, ColIdx)

        OpenXML.AddThreadedComment(DocInfo, XCell, "Author Name", "Comment Text Goes Here")

        OpenXML.FinalizeComments(DocInfo)
    End Sub
End Class
票数 0
EN

Stack Overflow用户

发布于 2022-06-28 14:54:23

太棒了-我正经历着这场斗争。-)我必须对代码进行以下修改才能在我的情况下工作。如果没有这些更改,Excel就无法打开结果文档。

仍然失败的是从一个ClosedXML生成的文档开始,该文档包含一些旧的注释。

xmlns:o=\"urn:schemas-microsoft-com的两个位置上的

  1. 移除反斜杠

  1. 在这里添加ToUpper,GUID需要大写:

Dim AuthorGUID As String = "{“& Guid.NewGuid().ToString().ToUpper() & "}"

  1. 确保x:tableParts元素在sheet中的x:legacyDrawing元素之后

Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart) Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID} Dim tableXMLElement =.Id x.GetType (TableParts)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71769165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档