Генератор HTML таблиць в Excel

Як перетворити таблицю Excel в HTML за допомогою VBA

Excel дуже зручно використовувати для створення та редагування таблиць, але іноді готові дані потрібно перенести на вебсайт у форматі HTML. Звичайне копіювання таблиці з Excel не завжди дає потрібний результат, особливо якщо необхідно отримати чистий HTML-код.

Тож я вирішив написав простий генератор HTML таблиць в Excel.

Як працює генератор HTML таблиць в Excel

Принцип роботи програми дуже простий і не потребує ніяких спеціальних налаштувань:

  1. Запустіть макрос «HTML_Table_Generator».
  2. Виділити комірки з даними, які потрібно перенести в HTML таблицю.
  3. Оберіть які комірки будуть формувати заголовок таблиці. Якщо обрати «по горизонтальні», то заголовком буде перший горизонтальний рядок. Якщо обрати «по вертикалі», то заголовком буде перший стовпець.
  4. Натисніть кнопку «Згенерувати».

Після цього програма автоматично формує готову HTML таблицю із зазначеними заголовками та даними. Вам не потрібно вручну створювати теги <table>, <tr>, <th> та <td>, оскільки генератор робить це автоматично.

Як додати VBA макрос для створення HTML таблиць в Excel

Додати VBA макрос для створення HTML таблиць в Excel можна двома способами. Перший варіант передбачає імпорт уже готової форми та модуля з файлами програми.

Це найпростіший спосіб, якщо потрібно швидко встановити генератор і почати ним користуватися.

Другий варіант підійде тим, хто хоче створити програму самостійно та краще зрозуміти принцип роботи VBA в Excel. У цьому випадку форма створюється вручну в редакторі Visual Basic, на неї додаються текстові поля та кнопки, а потім у відповідні елементи вставляється необхідний код.

Імпорт готової форми та модуля для генерації HTML таблиць в Excel

Якщо ви хочете швидко додати генератор HTML таблиць в Excel, необов'язково створювати форму та програмний код вручну. Найпростіший варіант – завантажити готові файли програми та імпортувати їх у редактор VBA.

Завантажити макрос формування HTML таблиць в Excel

Імпортувати будемо 2 файли – .frm та .bas. Щоб це зробити правильно, дотримуйтеся покрокової інструкції.

Крок 1. Завантажте файли генератора

Генератор HTML таблиць в Excel

Завантажте архів із готовими файлами генератора HTML таблиць. Розпакуйте його у будь-яку зручну папку на комп'ютері.

Після розпакування у вас повинні бути файли форми та модуля, які використовуються програмою. Не потрібно відкривати їх подвійним клацанням – вони імпортуються безпосередньо через редактор VBA.

Крок 2. Відкрийте редактор VBA

Відкрийте книгу Excel, в якій хочете використовувати генератор, і натисніть комбінацію клавіш Alt + F11.

Відкриється редактор Microsoft Visual Basic for Applications. Саме тут знаходяться форми, модулі та інший програмний код, який використовується макросами Excel.

Крок 3. Імпортуйте форму

VBA Import File

У лівій частині редактора VBA знайдіть проект відкритої книги. Зазвичай він має назву на зразок VBAProject (Книга1).

Натисніть на проект правою кнопкою миші та виберіть пункт Import File.

У вікні вибору файлу знайдіть розпакований файл форми з розширенням .frm та відкрийте його.

Після цього форма з'явиться у вашому VBA-проєкті.

Крок 4. Імпортуйте модуль

VBA Code

Тепер таким самим способом імпортуйте файл модуля з розширенням .bas.

Натисніть правою кнопкою миші на проект книги, виберіть Import File, знайдіть файл модуля та підтвердьте імпорт.

У результаті у проекті повинні з'явитися імпортована форма та стандартний модуль із кодом запуску програми.

Крок 5. Збережіть книгу у форматі з підтримкою макросів

Це важливий момент. Якщо книга Excel зберігається у звичайному форматі .xlsx, VBA-код у ній зберігатися не буде.

Тому відкрийте Файл → Зберегти як та виберіть формат Книга Excel з підтримкою макросів (*.xlsm).

Після збереження закрийте редактор VBA за допомогою Alt + F11.

Крок 6. Запустіть генератор HTML таблиць

Поверніться до Excel і відкрийте список макросів за допомогою Alt + F8.

У списку знайдіть макрос HTML_Table_Generator, виберіть його та натисніть Виконати.

Після запуску на екрані з'явиться форма генератора. Тепер можна вибрати комірки із даними таблиці та натиснути кнопку Згенерувати.

Програма сформує HTML-код, який можна скопіювати та вставити у HTML-документ або редактор сайту.

Зверніть увагу!

Під час першого запуску Excel може показати попередження про макроси. Це стандартний механізм безпеки Microsoft Office. Запускайте макроси лише з файлів і джерел, яким ви довіряєте.

Також важливо імпортувати обидва файли – форму та модуль. Форма відповідає за інтерфейс генератора, а модуль містить процедуру запуску форми. Якщо імпортувати тільки один із них, програма може не запуститися належним чином.

Самостійне створення VBA програми для перетворення таблиці Excel в HTML

Якщо ви не хочете імпортувати готові файли, форму генератора можна створити власноруч у редакторі VBA. Такий варіант трохи довший, але дозволяє розібратися з будовою програми та за потреби змінити її інтерфейс відповідно до власних потреб.

Створення VBA форми

VBA Insert

Для початку відкрийте редактор VBA за допомогою комбінації Alt + F11. У меню виберіть Insert → UserForm. На аркуші форми потрібно розмістити текстові поля та кнопки, які будуть використовуватися для вибору діапазонів, генерації та копіювання HTML-коду.

Щоб програмний код правильно взаємодіяв із елементами форми, важливо вказати для них відповідні імена у властивості Name. Також необхідно задати деякі додаткові властивості, зокрема розмір полів, їхній режим редагування та підписи кнопок.

Щоб не витрачати час на опис кожної властивості окремо, усі необхідні параметри я звів в одну таблицю:

Елемент Властивість Name Тип Основні налаштування
Поле «Діапазон комірок» txtRange TextBox Width = 320, Locked = True
Кнопка «Вибрати» cmdSelectRange CommandButton Caption = "Вибрати…"
Перемикач «По горизонталі» optHorizontal OptionButton Caption = "По горизонталі (перший рядок — заголовки)"
Перемикач «По вертикалі» optVertical OptionButton Caption = "По вертикалі (перша колонка — заголовки)"
Поле HTML txtHTML TextBox MultiLine = True, ScrollBars = 3, Width = 480, Height = 280
Кнопка «Згенерувати» cmdGenerate CommandButton Caption = "Згенерувати HTML"
Кнопка «Копіювати» cmdCopy CommandButton Caption = "Копіювати в буфер"
Кнопка «Очистити» cmdClear CommandButton Caption = "Очистити"

Розташування елементів на формі можна змінити на власний розсуд. Головне — використовувати саме ті значення властивості Name, які наведені в таблиці, оскільки вони безпосередньо прописані у VBA-коді. Якщо назвати, наприклад, поле txtHeaderRange інакше, то відповідна частина програми не зможе звернутися до нього за старою назвою.

Після додавання всіх елементів залишиться вставити програмний код у модуль форми. Для цього двічі клацніть по створеній UserForm у редакторі VBA та вставте код, наведений нижче.

Option Explicit

' =============================================================================
' ІНІЦІАЛІЗАЦІЯ ФОРМИ
' =============================================================================
Private Sub UserForm_Initialize()
    txtRange.Value = ""
    txtHTML.Value = ""
    optHorizontal.Value = True
    optVertical.Value = False
End Sub

' =============================================================================
' ДОПОМІЖНІ ФУНКЦІЇ
' =============================================================================
Private Function GetCellValue(cell As Range) As String
    If cell.MergeCells Then
        GetCellValue = Trim(cell.MergeArea.Cells(1, 1).Text)
    Else
        GetCellValue = Trim(cell.Text)
    End If
End Function

Private Function IsMainCell(cell As Range) As Boolean
    If Not cell.MergeCells Then
        IsMainCell = True
    Else
        IsMainCell = (cell.Address = cell.MergeArea.Cells(1, 1).Address)
    End If
End Function

Private Function GetRowspan(cell As Range, currentRow As Long, totalRows As Long) As Long
    If cell.MergeCells Then
        Dim rs As Long
        rs = cell.MergeArea.Rows.Count
        If currentRow + rs - 1 > totalRows Then
            rs = totalRows - currentRow + 1
        End If
        GetRowspan = rs
    Else
        GetRowspan = 1
    End If
End Function

Private Function GetColspan(cell As Range, currentCol As Long, totalCols As Long) As Long
    If cell.MergeCells Then
        Dim cs As Long
        cs = cell.MergeArea.Columns.Count
        If currentCol + cs - 1 > totalCols Then
            cs = totalCols - currentCol + 1
        End If
        GetColspan = cs
    Else
        GetColspan = 1
    End If
End Function

Private Function BuildCellAttr(cell As Range, r As Long, c As Long, totalRows As Long, totalCols As Long) As String
    Dim attr As String
    Dim cs As Long
    Dim rs As Long
    cs = GetColspan(cell, c, totalCols)
    rs = GetRowspan(cell, r, totalRows)
    If cs > 1 Then attr = attr & " colspan=""" & cs & """"
    If rs > 1 Then attr = attr & " rowspan=""" & rs & """"
    BuildCellAttr = attr
End Function

Private Function EscapeHTML(ByVal src As String) As String
    Dim s As String
    s = src
    s = Replace(s, "&", "&amp;")
    s = Replace(s, "<", "&lt;")
    s = Replace(s, ">", "&gt;")
    s = Replace(s, """", "&quot;")
    EscapeHTML = s
End Function

' =============================================================================
' ВИБІР ДІАПАЗОНУ
' =============================================================================
Private Sub cmdSelectRange_Click()
    Dim rng As Range
    
    On Error Resume Next
    Set rng = Application.InputBox( _
        Prompt:="Виділіть блок комірок." & vbCrLf & _
                "• По горизонталі: перший рядок — заголовки, решта — дані" & vbCrLf & _
                "• По вертикалі: перша колонка — заголовки, решта — дані", _
        Title:="Вибір діапазону", _
        Type:=8)
    On Error GoTo 0
    
    If Not rng Is Nothing Then
        txtRange.Value = rng.Address(External:=True)
    End If
End Sub

' =============================================================================
' ЗГЕНЕРУВАТИ HTML
' =============================================================================
Private Sub cmdGenerate_Click()
    Dim rng          As Range
    Dim html         As String
    Dim r            As Long
    Dim c            As Long
    Dim totalRows    As Long
    Dim totalCols    As Long
    Dim cell         As Range
    Dim attr         As String
    Dim cs           As Long
    Dim rs           As Long
    Dim rr           As Long
    Dim cc           As Long
    Dim hasContent   As Boolean
    
    ' --- Перевірка діапазону ------------------------------------------------
    If Trim(txtRange.Value) = "" Then
        MsgBox "Спочатку виберіть діапазон комірок.", vbExclamation, "Не вибрано діапазон"
        Exit Sub
    End If
    
    On Error GoTo RangeError
    Set rng = Range(txtRange.Value)
    On Error GoTo 0
    
    totalRows = rng.Rows.Count
    totalCols = rng.Columns.Count
    
    ' --- Перевірка розміру --------------------------------------------------
    If optHorizontal.Value Then
        If totalRows < 2 Then
            MsgBox "Для режиму «По горизонталі» потрібно мінімум 2 рядки:" & vbCrLf & _
                   "1-й — заголовки, 2-й і далі — дані.", vbExclamation, "Замало рядків"
            Exit Sub
        End If
    Else
        If totalCols < 2 Then
            MsgBox "Для режиму «По вертикалі» потрібно мінімум 2 колонки:" & vbCrLf & _
                   "1-ша — заголовки, 2-га і далі — дані.", vbExclamation, "Замало колонок"
            Exit Sub
        End If
    End If
    
    ' --- Початок HTML -------------------------------------------------------
    html = "<div class=""table-responsive"">" & vbCrLf
    html = html & "    <table class=""table table-striped"">" & vbCrLf
    
    ' ========================================================================
    ' РЕЖИМ: ПО ГОРИЗОНТАЛІ
    ' ========================================================================
    If optHorizontal.Value Then
        
        ' --- thead (перший рядок) ---
        Dim occupiedH() As Boolean
        ReDim occupiedH(1 To 1, 1 To totalCols)
        
        html = html & "        <thead>" & vbCrLf
        html = html & "            <tr>" & vbCrLf
        For c = 1 To totalCols
            If occupiedH(1, c) Then GoTo SkipCellH1
            Set cell = rng.Cells(1, c)
            If IsMainCell(cell) Then
                attr = BuildCellAttr(cell, 1, c, 1, totalCols)
                html = html & "                <th" & attr & ">" & EscapeHTML(GetCellValue(cell)) & "</th>" & vbCrLf
                cs = GetColspan(cell, c, totalCols)
                For cc = c To c + cs - 1
                    If cc <= totalCols Then occupiedH(1, cc) = True
                Next cc
            End If
SkipCellH1:
        Next c
        html = html & "            </tr>" & vbCrLf
        html = html & "        </thead>" & vbCrLf
        
        ' --- tbody (решта рядків) ---
        Dim occupiedB() As Boolean
        ReDim occupiedB(2 To totalRows, 1 To totalCols)
        
        html = html & "        <tbody>" & vbCrLf
        Dim dataRowCount As Long
        dataRowCount = 0
        
        For r = 2 To totalRows
            hasContent = False
            For c = 1 To totalCols
                If Not occupiedB(r, c) And IsMainCell(rng.Cells(r, c)) Then
                    hasContent = True
                    Exit For
                End If
            Next c
            
            If Not hasContent Then GoTo SkipRowH
            
            html = html & "            <tr>" & vbCrLf
            For c = 1 To totalCols
                If occupiedB(r, c) Then GoTo SkipCellH2
                Set cell = rng.Cells(r, c)
                If IsMainCell(cell) Then
                    attr = BuildCellAttr(cell, r, c, totalRows, totalCols)
                    html = html & "                <td" & attr & ">" & EscapeHTML(GetCellValue(cell)) & "</td>" & vbCrLf
                    rs = GetRowspan(cell, r, totalRows)
                    cs = GetColspan(cell, c, totalCols)
                    For rr = r To r + rs - 1
                        For cc = c To c + cs - 1
                            If rr <= totalRows And cc <= totalCols Then
                                occupiedB(rr, cc) = True
                            End If
                        Next cc
                    Next rr
                End If
SkipCellH2:
            Next c
            html = html & "            </tr>" & vbCrLf
            dataRowCount = dataRowCount + 1
SkipRowH:
        Next r
        html = html & "        </tbody>" & vbCrLf
        
        html = html & "    </table>" & vbCrLf
        html = html & "</div>"
        
        MsgBox "HTML-таблицю сформовано!" & vbCrLf & _
               "Режим: по горизонталі" & vbCrLf & _
               "Колонок: " & totalCols & ", рядків даних: " & dataRowCount, _
               vbInformation, "Готово"
    
    ' ========================================================================
    ' РЕЖИМ: ПО ВЕРТИКАЛІ
    ' ========================================================================
    Else
        
        Dim occupiedV() As Boolean
        ReDim occupiedV(1 To totalRows, 1 To totalCols)
        
        html = html & "        <tbody>" & vbCrLf
        Dim rowCount As Long
        rowCount = 0
        
        For r = 1 To totalRows
            hasContent = False
            For c = 1 To totalCols
                If Not occupiedV(r, c) And IsMainCell(rng.Cells(r, c)) Then
                    hasContent = True
                    Exit For
                End If
            Next c
            
            If Not hasContent Then GoTo SkipRowV
            
            html = html & "            <tr>" & vbCrLf
            For c = 1 To totalCols
                If occupiedV(r, c) Then GoTo SkipCellV
                Set cell = rng.Cells(r, c)
                If IsMainCell(cell) Then
                    attr = BuildCellAttr(cell, r, c, totalRows, totalCols)
                    If c = 1 Then
                        html = html & "                <th" & attr & ">" & EscapeHTML(GetCellValue(cell)) & "</th>" & vbCrLf
                    Else
                        html = html & "                <td" & attr & ">" & EscapeHTML(GetCellValue(cell)) & "</td>" & vbCrLf
                    End If
                    rs = GetRowspan(cell, r, totalRows)
                    cs = GetColspan(cell, c, totalCols)
                    For rr = r To r + rs - 1
                        For cc = c To c + cs - 1
                            If rr <= totalRows And cc <= totalCols Then
                                occupiedV(rr, cc) = True
                            End If
                        Next cc
                    Next rr
                End If
SkipCellV:
            Next c
            html = html & "            </tr>" & vbCrLf
            rowCount = rowCount + 1
SkipRowV:
        Next r
        html = html & "        </tbody>" & vbCrLf
        
        html = html & "    </table>" & vbCrLf
        html = html & "</div>"
        
        MsgBox "HTML-таблицю сформовано!" & vbCrLf & _
               "Режим: по вертикалі" & vbCrLf & _
               "Рядків: " & rowCount & ", колонок даних: " & (totalCols - 1), _
               vbInformation, "Готово"
    End If
    
    txtHTML.Value = html
    Exit Sub

RangeError:
    MsgBox "Не вдалося визначити діапазон." & vbCrLf & _
           "Переконайтесь, що адреса вказана правильно, або скористайтесь кнопкою «Вибрати діапазон…».", _
           vbCritical, "Помилка"
End Sub

' =============================================================================
' КОПІЮВАННЯ В БУФЕР
' =============================================================================
Private Sub cmdCopy_Click()
    If Trim(txtHTML.Value) = "" Then
        MsgBox "Спочатку згенеруйте HTML-таблицю.", vbExclamation, "Немає даних"
        Exit Sub
    End If
    
    Me.txtHTML.SetFocus
    Me.txtHTML.SelStart = 0
    Me.txtHTML.SelLength = Len(Me.txtHTML.Text)
    Me.txtHTML.Copy
    
    MsgBox "HTML-код скопійовано в буфер обміну!", vbInformation, "Готово"
End Sub

' =============================================================================
' ОЧИЩЕННЯ
' =============================================================================
Private Sub cmdClear_Click()
    txtRange.Value = ""
    txtHTML.Value = ""
    optHorizontal.Value = True
    optVertical.Value = False
    txtRange.SetFocus
End Sub

Створення модуля

Окремо потрібно створити звичайний модуль VBA, у який додається невеликий макрос запуску форми. Саме його користувач буде запускати через список доступних макросів Excel.

Відкрийте редактор VBA за допомогою комбінації Alt + F11. У меню виберіть Insert → Module. Вставте у вікно цей код:

Option Explicit

Sub HTML_Table_Generator()
    frmHTMLTableFlex.Show
End Sub

Збережіть книгу у форматі з підтримкою макросів.

Таким чином, для повноцінної роботи генератора потрібно створити лише форму з переліченими вище елементами та один стандартний модуль. Увесь основний функціонал програми вже реалізований у готовому VBA-коді, тому вручну писати логіку вибору діапазонів, формування HTML або копіювання результату не потрібно.

Main Menu