programing

Excel 셀에서 형식이 지정된 텍스트에 태그가 있는 HTML 텍스트

sourcejob 2023. 5. 24. 22:06
반응형

Excel 셀에서 형식이 지정된 텍스트에 태그가 있는 HTML 텍스트

HTML을 가져다가 excel로 가져와서 리치 텍스트로 포맷할 수 있는 방법이 있습니까(VBA를 사용하는 것이 좋습니다)?기본적으로 Excel 셀에 붙여넣을 때 다음과 같은 기능을 사용하려고 합니다.

<html><p>This is a test. Will this text be <b>bold</b> or <i>italic</i></p></html>

여기에:

이것은 테스트입니다.텍스트를 굵게 표시할 것인지 기울임꼴로 표시할 것인지 여부

네, 가능합니다.실제로 Internet Explorer(인터넷 익스플로러)가 여러분을 위해 더러운 일을 하도록 하십시오.

나의 가정

  1. 나는 html 텍스트가 Sheet1의 Cell A1에 있다고 가정합니다.변수를 대신 사용할 수도 있습니다.
  2. 만약 당신이 html 값으로 가득 찬 열을 가지고 있다면, 아래 코드를 루프에 넣기만 하면 됩니다.

코드

Sub Sample()
    Dim Ie As Object
    
    Set Ie = CreateObject("InternetExplorer.Application")
    
    With Ie
        .Visible = False
        
        .Navigate "about:blank"
        
        .document.body.InnerHTML = Sheets("Sheet1").Range("A1").Value
        
        .document.body.createtextrange.execCommand "Copy"
        ActiveSheet.Paste Destination:=Sheets("Sheet1").Range("A1")
        
        .Quit
    End With
End Sub

스냅샷

여기에 이미지 설명 입력

저는 BornToCode가 원래 솔루션의 코멘트에서 처음 확인한 것과 동일한 오류를 발견했습니다.Excel과 VBA에 익숙하지 않아서 tiQ를 구현하는 방법을 찾는 데 몇 초가 걸렸습니다.U의 해결책.그래서 아래에 "For Dummies" 솔루션으로 게시합니다.

  1. Excel에서 먼저 개발자 모드 활성화: 링크
  2. 개발자 탭 > Visual Basic 선택
  3. 보기 > 코드 클릭
  4. 셀 참조가 정확해야 하는 라인을 업데이트하는 아래 코드를 붙여넣습니다.
  5. 녹색 실행 화살표를 클릭하거나 F5 키를 누릅니다.
Sub Sample()
    Dim Ie As Object
    Set Ie = CreateObject("InternetExplorer.Application")
    With Ie
        .Visible = False
        .Navigate "about:blank"
        .document.body.InnerHTML = Sheets("Sheet1").Range("I2").Value
             'update to the cell that contains HTML you want converted
        .ExecWB 17, 0
             'Select all contents in browser
        .ExecWB 12, 2
             'Copy them
        ActiveSheet.Paste Destination:=Sheets("Sheet1").Range("J2")
             'update to cell you want converted HTML pasted in
        .Quit
    End With
End Sub

HTML 코드를 클립보드에 복사하고 특수 코드를 유니코드 텍스트로 다시 붙여넣을 수 있습니다.Excel은 셀에서 HTML을 렌더링합니다. 게시물 http://www.dailydoseofexcel.com/archives/2005/02/23/html-in-cells-ii/ 을 확인해 보세요.

게시물의 관련 매크로 코드:

Private Sub Worksheet_Change(ByVal Target As Range)

   Dim objData As DataObject
   Dim sHTML As String
   Dim sSelAdd As String

   Application.EnableEvents = False

   If Target.Cells.Count = 1 Then
      If LCase(Left(Target.Text, 6)) = "<html>" Then
         Set objData = New DataObject

         sHTML = Target.Text

         objData.SetText sHTML
         objData.PutInClipboard

         sSelAdd = Selection.Address
         Target.Select
         Me.PasteSpecial "Unicode Text"
         Me.Range(sSelAdd).Select

      End If
   End If

   Application.EnableEvents = True

End Sub

IE 예제가 작동하지 않으면 이 예제를 사용합니다.어쨌든, 이것은 IE 인스턴스를 시작하는 것보다 빠를 것입니다.

다음은 다음을 기반으로 한 완벽한 솔루션입니다.
http://www..com/archives/2005/02/23/html-in-cells-ii/http://www.dailydoseofexcel.com/archives/2005/02/23/html-in-cells-ii/

내부 HTML이 모든 숫자(예: '12345')인 경우, HTML 형식은 숫자를 다르게 처리하기 때문에 엑셀에서 완전히 작동하지 않습니다. 그러나 끝에 문자(예: 12345 + "&nbsp;" 형식)를 추가합니다.

Sub test()
    Cells(1, 1).Value = "<HTML>1<font color=blue>a</font>" & _
                        "23<font color=red>4</font></HTML>"
    Dim rng As Range
    Set rng = ActiveSheet.Cells(1, 1)
    Worksheet_Change rng, ActiveSheet
End Sub


Private Sub Worksheet_Change(ByVal Target As Range, ByVal sht As Worksheet)

    Dim objData As DataObject ' Set a reference to MS Forms 2.0
    Dim sHTML As String
    Dim sSelAdd As String

    Application.EnableEvents = False

    If Target.Cells.Count = 1 Then

            Set objData = New DataObject
            sHTML = Target.Text
            objData.SetText sHTML
            objData.PutInClipboard
            Target.Select
            sht.PasteSpecial Format:="Unicode Text"
    End If

    Application.EnableEvents = True

End Sub

이 실이 오래된 것은 알지만, 내부를 할당한 후에HTML, ExecWB를 사용할 수 있습니다.

.ExecWB 17, 0
'Select all contents in browser
.ExecWB 12, 2
'Copy them

그런 다음 내용을 엑셀에 붙여넣기만 하면 됩니다.이러한 메소드는 런타임 오류가 발생하기 쉬우나 디버그 모드에서 한두 번 시도한 후에는 정상적으로 작동하므로 오류가 발생하면 Excel에 다시 시도하라고 말해야 할 수 있습니다.이 오류 처리기를 서브에 추가하여 해결했으며, 정상적으로 작동합니다.

Sub ApplyHTML()
  On Error GoTo ErrorHandler
    ...
  Exit Sub

ErrorHandler:
    Resume 
    'I.e. re-run the line of code that caused the error
Exit Sub
     
End Sub

좋아요! 아주 매끈해요.

하지만 Excel이 병합된 셀에 붙여넣는 것을 허용하지 않고 "대상" 셀 아래에 연속된 행으로 분할된 결과를 붙여넣는 것이 저에게는 효과가 없다는 것을 의미했기 때문에 실망했습니다.저는 몇 번의 조정(합병/재합병 등)을 시도했지만, Excel은 휴식 시간 아래로 모든 것을 떨어뜨려 막다른 골목에 이르렀습니다.

결국, 저는 단순 태그를 처리하고 병합된 필드에서 문제를 일으키는 "원본" 유니코드 변환기를 사용하지 않는 루틴을 고안했습니다.다른 사람들이 이것을 유용하게 생각하기를 바랍니다.

Public Sub AddHTMLFormattedText(rngA As Range, strHTML As String, Optional blnShowBadHTMLWarning As Boolean = False)
    ' Adds converts text formatted with basic HTML tags to formatted text in an Excel cell
    ' NOTE: Font Sizes not handled perfectly per HTML standard, but I find this method more useful!

    Dim strActualText As String, intSrcPos As Integer, intDestPos As Integer, intDestSrcEquiv() As Integer
    Dim varyTags As Variant, varTag As Variant, varEndTag As Variant, blnTagMatch As Boolean
    Dim intCtr As Integer
    Dim intStartPos As Integer, intEndPos As Integer, intActualStartPos As Integer, intActualEndPos As Integer
    Dim intFontSizeStartPos As Integer, intFontSizeEndPos As Integer, intFontSize As Integer

    varyTags = Array("<b>", "</b>", "<i>", "</i>", "<u>", "</u>", "<sub>", "</sub>", "<sup>", "</sup>")

    ' Remove unhandled/unneeded tags, convert <br> and <p> tags to line feeds
    strHTML = Trim(strHTML)
    strHTML = Replace(strHTML, "<html>", "")
    strHTML = Replace(strHTML, "</html>", "")
    strHTML = Replace(strHTML, "<p>", "")
    While LCase(Right$(strHTML, 4)) = "</p>" Or LCase(Right$(strHTML, 4)) = "<br>"
        strHTML = Left$(strHTML, Len(strHTML) - 4)
        strHTML = Trim(strHTML)
    Wend
    strHTML = Replace(strHTML, "<br>", vbLf)
    strHTML = Replace(strHTML, "</p>", vbLf)

    strHTML = Trim(strHTML)

    ReDim intDestSrcEquiv(1 To Len(strHTML))
    strActualText = ""
    intSrcPos = 1
    intDestPos = 1
    Do While intSrcPos <= Len(strHTML)
        blnTagMatch = False
        For Each varTag In varyTags
            If LCase(Mid$(strHTML, intSrcPos, Len(varTag))) = varTag Then
                blnTagMatch = True
                intSrcPos = intSrcPos + Len(varTag)
                If intSrcPos > Len(strHTML) Then Exit Do
                Exit For
            End If
        Next
        If blnTagMatch = False Then
            varTag = "<font size"
            If LCase(Mid$(strHTML, intSrcPos, Len(varTag))) = varTag Then
                blnTagMatch = True
                intEndPos = InStr(intSrcPos, strHTML, ">")
                intSrcPos = intEndPos + 1
                If intSrcPos > Len(strHTML) Then Exit Do
            Else
                varTag = "</font>"
                If LCase(Mid$(strHTML, intSrcPos, Len(varTag))) = varTag Then
                    blnTagMatch = True
                    intSrcPos = intSrcPos + Len(varTag)
                    If intSrcPos > Len(strHTML) Then Exit Do
                End If
            End If
        End If
        If blnTagMatch = False Then
            strActualText = strActualText & Mid$(strHTML, intSrcPos, 1)
            intDestSrcEquiv(intSrcPos) = intDestPos
            intDestPos = intDestPos + 1
            intSrcPos = intSrcPos + 1
        End If
    Loop

    ' Clear any bold/underline/italic/superscript/subscript formatting from cell
    rngA.Font.Bold = False
    rngA.Font.Underline = False
    rngA.Font.Italic = False
    rngA.Font.Subscript = False
    rngA.Font.Superscript = False

    rngA.Value = strActualText

    ' Now start applying Formats!"
    ' Start with Font Size first
    intSrcPos = 1
    intDestPos = 1
    Do While intSrcPos <= Len(strHTML)
        varTag = "<font size"
        If LCase(Mid$(strHTML, intSrcPos, Len(varTag))) = varTag Then
            intFontSizeStartPos = InStr(intSrcPos, strHTML, """") + 1
            intFontSizeEndPos = InStr(intFontSizeStartPos, strHTML, """") - 1
            If intFontSizeEndPos - intFontSizeStartPos <= 3 And intFontSizeEndPos - intFontSizeStartPos > 0 Then
                Debug.Print Mid$(strHTML, intFontSizeStartPos, intFontSizeEndPos - intFontSizeStartPos + 1)
                If Mid$(strHTML, intFontSizeStartPos, 1) = "+" Then
                    intFontSizeStartPos = intFontSizeStartPos + 1
                    intFontSize = 11 + 2 * Mid$(strHTML, intFontSizeStartPos, intFontSizeEndPos - intFontSizeStartPos + 1)
                ElseIf Mid$(strHTML, intFontSizeStartPos, 1) = "-" Then
                    intFontSizeStartPos = intFontSizeStartPos + 1
                    intFontSize = 11 - 2 * Mid$(strHTML, intFontSizeStartPos, intFontSizeEndPos - intFontSizeStartPos + 1)
                Else
                    intFontSize = Mid$(strHTML, intFontSizeStartPos, intFontSizeEndPos - intFontSizeStartPos + 1)
                End If
            Else
                ' Error!
                GoTo HTML_Err
            End If
            intEndPos = InStr(intSrcPos, strHTML, ">")
            intSrcPos = intEndPos + 1
            intStartPos = intSrcPos
            If intSrcPos > Len(strHTML) Then Exit Do
            While intDestSrcEquiv(intStartPos) = 0 And intStartPos < Len(strHTML)
                intStartPos = intStartPos + 1
            Wend
            If intStartPos >= Len(strHTML) Then GoTo HTML_Err ' HTML is bad!
            varEndTag = "</font>"
            intEndPos = InStr(intSrcPos, LCase(strHTML), varEndTag)
            If intEndPos = 0 Then GoTo HTML_Err ' HTML is bad!
            While intDestSrcEquiv(intEndPos) = 0 And intEndPos > intSrcPos
                intEndPos = intEndPos - 1
            Wend
            If intEndPos > intSrcPos Then
                intActualStartPos = intDestSrcEquiv(intStartPos)
                intActualEndPos = intDestSrcEquiv(intEndPos)
                rngA.Characters(intActualStartPos, intActualEndPos - intActualStartPos + 1) _
                    .Font.Size = intFontSize
            End If
        End If
        intSrcPos = intSrcPos + 1
    Loop

    'Now do remaining tags
    intSrcPos = 1
    intDestPos = 1
    Do While intSrcPos <= Len(strHTML)
        If intDestSrcEquiv(intSrcPos) = 0 Then
            ' This must be a Tag!
            For intCtr = 0 To UBound(varyTags) Step 2
                varTag = varyTags(intCtr)
                intStartPos = intSrcPos + Len(varTag)
                While intDestSrcEquiv(intStartPos) = 0 And intStartPos < Len(strHTML)
                    intStartPos = intStartPos + 1
                Wend
                If intStartPos >= Len(strHTML) Then GoTo HTML_Err ' HTML is bad!
                If LCase(Mid$(strHTML, intSrcPos, Len(varTag))) = varTag Then
                    varEndTag = varyTags(intCtr + 1)
                    intEndPos = InStr(intSrcPos, LCase(strHTML), varEndTag)
                    If intEndPos = 0 Then GoTo HTML_Err ' HTML is bad!
                    While intDestSrcEquiv(intEndPos) = 0 And intEndPos > intSrcPos
                        intEndPos = intEndPos - 1
                    Wend
                    If intEndPos > intSrcPos Then
                        intActualStartPos = intDestSrcEquiv(intStartPos)
                        intActualEndPos = intDestSrcEquiv(intEndPos)
                        With rngA.Characters(intActualStartPos, intActualEndPos - intActualStartPos + 1).Font
                            If varTag = "<b>" Then
                                .Bold = True
                            ElseIf varTag = "<i>" Then
                                .Italic = True
                            ElseIf varTag = "<u>" Then
                                .Underline = True
                            ElseIf varTag = "<sup>" Then
                                .Superscript = True
                            ElseIf varTag = "<sub>" Then
                                .Subscript = True
                            End If
                        End With
                    End If
                    intSrcPos = intSrcPos + Len(varTag) - 1
                    Exit For
                End If
            Next
        End If
        intSrcPos = intSrcPos + 1
        intDestPos = intDestPos + 1
    Loop
Exit_Sub:
    Exit Sub
HTML_Err:
    ' There was an error with the Tags. Show warning if requested.
    If blnShowBadHTMLWarning Then
        MsgBox "There was an error with the Tags in the HTML file. Could not apply formatting."
    End If
End Sub

이는 태그 중첩과는 상관이 없으며, 열린 모든 태그에 대한 닫기 태그만 필요하며, 열린 태그와 가장 가까운 닫기 태그가 시작 태그에 적용된다고 가정합니다.적절하게 중첩된 태그는 정상적으로 작동하지만, 잘못 중첩된 태그는 거부되지 않으며 작동하거나 작동하지 않을 수 있습니다.

HTML/Word를 Excel 모양으로 배치하고 Excel 셀에서 찾기

  1. 내 HTML을 임시 파일에 씁니다.
  2. Word Interop을 통해 임시 파일을 엽니다.
  3. Word에서 클립보드로 복사합니다.
  4. Interop을 통해 Excel을 엽니다.
  5. 셀을 범위로 설정 및 선택합니다.
  6. 특수 파일을 "Microsoft Word 문서 개체"로 붙여넣기
  7. Excel 행을 Shape 높이로 조정합니다.

이런 식으로 테이블과 다른 것들이 있는 HTML도 여러 셀에 걸쳐 분할되지 않습니다.

    private void btnPutHTMLIntoExcelShape_Click(object sender, EventArgs e)
    {
        var fFile = new FileInfo(@"C:\Temp\temp.html");
        StreamWriter SW = fFile.CreateText();
        SW.Write(hecNote.DocumentHtml);
        SW.Close();

        Word.Application wrdApplication;
        Word.Document wrdDocument;
        wrdApplication = new Word.Application();
        wrdApplication.Visible = true;

        wrdDocument = wrdApplication.Documents.Add(@"C:\Temp\temp.html");
        wrdDocument.ActiveWindow.Selection.WholeStory();
        wrdDocument.ActiveWindow.Selection.Copy();

        Excel.Application excApplication;
        Excel.Workbook excWorkbook;
        Excel._Worksheet excWorksheet;
        Excel.Range excRange = null;

        excApplication = new Excel.Application();
        excApplication.Visible = true;
        excWorkbook = excApplication.Workbooks.Add(Type.Missing);
        excWorksheet = (Excel.Worksheet)excWorkbook.Worksheets.get_Item(1);
        excWorksheet.Name = "Work";
        excRange = excWorksheet.get_Range("A1");
        excRange.Select();

        excWorksheet.PasteSpecial("Microsoft Word Document Object");

        Excel.Shape O = excWorksheet.Shapes.Item(1);

        this.Text = $"{O.Height} x {O.Width}";
        ((Excel.Range)excWorksheet.Rows[1, Type.Missing]).RowHeight = O.Height;
    }

언급URL : https://stackoverflow.com/questions/9999713/html-text-with-tags-to-formatted-text-in-an-excel-cell

반응형