Excelの表をHTMLのTableに変換する関数

最近だとエディタやIDEが高機能になっているので、手でHTMLを書くということは少ないかもしれません。

しかし、そのエディタが使用しにくいということはありませんか?

自分はブログを書いたりする時にWordPressの表エディタを使っていたのですが、正直使いにくいと思っていました。

その点、Excelは間違いなく最強の表計算ソフトなので、使い勝手も抜群です。

そこで「HTMLを書く際には、Excelを使用する」というのが自分の定番となりました。

Excelで作ることにより、関数やオートフィルなどを使用して作成することが出来るため、作業効率も大幅にアップします。

具体的には、関数を使用して作成をしています。その方法について紹介をします。

自作関数でExcelからHTMLに変換

どのようにしているかと言うとExcelに自作関数を使用して、HTMLのタグを出力しています。

最も簡単なソースは以下ですかね。

Function HTMLTABLE(r As Range)
    Dim row As Long
    Dim column As Integer
    Dim ret As String
    Dim c As Object
    
    ret = "<table>"
    
    For row = 1 To r.Rows.Count
        ret = ret & "<tr>"
        For column = 1 To r.Columns.Count
            Set c = r.Item(row, column)
                If row = 1 Then
                    ret = ret & "<th>" & c.Value & "</th>"
                Else
                    ret = ret & "<td>" & c.Value & "</td>"
                End If
        Next
        ret = ret & "</tr>"
    Next
    
    ret = ret & "</table>"
    HTMLTABLE = ret
End Function

これをVBAで作成して、Excel側から呼び出せばいいだけです。

↑表全体を引数に入れて使います。=HTMLTABLE(E31:G34)

出力結果は以下のようになります。

<table><tr><th>商品</th><th>値段</th><th>個数</th></tr><tr><td>いちご</td><td>100</td><td>1</td></tr><tr><td>みかん</td><td>200</td><td>2</td></tr><tr><td>バナナ</td><td>300</td><td>3</td></tr></table>

これをHTMLに変換すると…

商品値段個数
いちご1001
みかん2002
バナナ3003

無事に表にすることが出来ました。

ExcelでHTMLを作成する利点と欠点

欠点としては、Excelの関数で改行に対応するのが難しいため、フォーマッタなどを使用したくなるところですね。

ただ上記のように、ブログに貼るだけの場合は、改行がないことでスペースを圧縮出来るというメリットもありますが。

利点は、自由にカスタマイズ可能だということです。既存のエディタだと拡張性がなかったりしますからね。

上記のソースだけでも1行目をTHタグにしているので、見出しタグを設定する手間が省けます。

自分の工夫次第で、どんどん生産性が上がるので個人的には超おすすめです。


使い勝手を上げる工夫

自分が実施しているカスタマイズを下記に紹介してみます。

Function HTMLTABLE(r As Range, _
                   Optional alignment As Boolean = False, _
                   Optional tableOption As String = "", _
                   Optional trOption As String = "", _
                   Optional thOption As String = "", _
                   Optional tdOption As String = "") As String
                   
    Dim ret As String
    Dim row As Long
    Dim column As Integer
    Dim c As Object
    Dim colspan As String
    Dim rowspan As String
    Dim align As String
    Dim valign As String
    Dim tableTag As String
    Dim trTag As String
    Dim thTag As String
    Dim tdTag As String
    
    If tableOption <> "" Then
        tableTag = "<table " & tableOption & ">"
    Else
        tableTag = "<table>"
    End If
    
    If trOption <> "" Then
        trTag = "<tr " & trOption & ">"
    Else
        trTag = "<tr>"
    End If
    
    If thOption <> "" Then
        thTag = "<th " & thOption
    Else
        thTag = "<th"
    End If
    
    If tdOption <> "" Then
        tdTag = "<td " & tdOption
    Else
        tdTag = "<td"
    End If
    
    ret = tableTag


    For row = 1 To r.Rows.Count
        ret = ret & trTag
        For column = 1 To r.Columns.Count
            Set c = r.Item(row, column)
            If (c.MergeCells And c.Address = c.MergeArea.Item(1).Address) Or Not c.MergeCells Then
                
                colspan = ""
                rowspan = ""
                If c.MergeCells And c.MergeArea.Columns.Count > 1 Then
                    colspan = " colspan=" & c.MergeArea.Columns.Count & " "
                End If
                If c.MergeCells And c.MergeArea.Rows.Count > 1 Then
                    rowspan = " rowspan=" & c.MergeArea.Rows.Count & " "
                End If
            
                align = ""
                valign = ""
                If alignment Then
                    Select Case Range(c.Address).HorizontalAlignment
                        Case xlLeft
                            align = " align = ""left"" "
                        Case xlCenter
                            align = " align = ""center"" "
                        Case xlRight
                            align = " align = ""right"" "
                        Case xlJustify
                            align = " align = ""justify"" "
                        Case Else
                    End Select
                    Select Case Range(c.Address).VerticalAlignment
                        Case xlTop
                            valign = " valign = ""top"" "
                        Case xlCenter
                            valign = " valign = ""middle"" "
                        Case xlBottom
                            valign = " valign = ""bottom"" "
                        Case Else
                    End Select
                End If
                
                If row = 1 Then
                    ret = ret & thTag & colspan & rowspan & align & valign & ">" & c.Value & "</th>"
                ElseIf c.Hyperlinks.Count > 0 Then
                    ret = ret & tdTag & colspan & rowspan & align & valign & ">" & a(c) & "</td>"
                Else
                    ret = ret & tdTag & colspan & rowspan & align & valign & ">" & c.Value & "</td>"
                End If
            End If
        Next column
        ret = ret & "</tr>"
    Next row
    
    ret = ret & "</table>"
    HTMLTABLE = ret
End Function

Function a(r As Range) As String
    Dim url As String

    If r.Hyperlinks.Count > 0 Then
        url = r.Hyperlinks(1).Address
        a = "<a href=""" & url & """ target=""_blank"">" & url & "</a>"
    Else
        a = r.Cells(1).Value
    End If
End Function

ごちゃごちゃしていて凄いわかりにくいです。自分用なので…すみません。

やっていることとしては

  • Excelにセルの結合があったら、rowSpanとcolSpanでHTMLも結合する
  • Excelにハイパーリンクが貼ってあったら、それはaタグに変換する
  • 出力する表のalignmentを省略可能引数で指定できる
  • 出力する表のTableタグのオプションを省略可能引数で指定できる
  • 出力する表のTrタグのオプションを省略可能引数で指定できる
  • 出力する表のTdタグのオプションを省略可能引数で指定できる
  • 出力する表のThタグのオプションを省略可能引数で指定できる

というものです。

書いてみて思いましたがalignmentはセルの書式設定を取得すれば引数指定する必要もなさそうですね。

とりあえず、

セル結合→rowSpanとcolSpan

ハイパーリンク→aタグ

は非常に便利なので個人的には手放せない感じです。その部分だけ解説してみます。

セル結合→rowSpanとcolSpan

            If (c.MergeCells And c.Address = c.MergeArea.Item(1).Address) Or Not c.MergeCells Then
                colspan = ""
                rowspan = ""
                If c.MergeCells And c.MergeArea.Columns.Count > 1 Then
                    colspan = " colspan=" & c.MergeArea.Columns.Count & " "
                End If
                If c.MergeCells And c.MergeArea.Rows.Count > 1 Then
                    rowspan = " rowspan=" & c.MergeArea.Rows.Count & " "
                End If

拡張for文でセルをループさせているのですが、結合されているかどうかはMergeCellsで取得することが出来るので、これで分岐させます。

MergeCellsの場合は、アドレスの1つ目のセルだけを処理するようにします。

そしてMergeArea.Columns.Countで縦の結合数、c.MergeArea.Rows.Countで横の結合数が取れるので、これをそれぞれrowSpanとcolSpanに設定すればOKです。

ハイパーリンク→aタグ

Function a(r As Range) As String
    Dim url As String

    If r.Hyperlinks.Count > 0 Then
        url = r.Hyperlinks(1).Address
        a = "<a href=""" & url & """ target=""_blank"">" & url & "</a>"
    Else
        a = r.Cells(1).Value
    End If
End Function

ハイパーリンクの数をHyperlinks.Countで取ることが出来ます。

これは2以上になることはあるのか?

自分の知識だとないと思うので、とりあえず1番目のリンクを取得して、リンク先URLとしてaタグに埋め込みます。

その他にできそうなこと

書式系はまだまだ追加できそうですね。

例えば

  • Excel側のセルに塗りつぶしがあったら、その色でHTMLも出力する
  • Excel側で太字が設定されていたら、HTMLの出力もBoldにする
  • Excel側でセルの幅を変更すると、HTMLのwidthも変更になる

とかです。まあCSSがしっかりしていれば設定不要な部分かもしれませんが。


コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)