SpreadSheetをHTMLのシンプルな表に変換するPythonスクリプト
<!-- markdown-mode-on -->
<img alt="bloggerlogo" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxuQ9ZnRR6ZBEQiBj7fhcsx1DIQwT6CANfRX8jfx5eDd0mzuvTSiY2mQT-zkjeugdWyPNSUMgdo4XZrpWfyqvDJy419ROBFm2eKGg88wvTcC0YcsoNLEdYO-oeMyQjT1C4AU2z8u2J3-CpjsNMyc8HTh4aAqgl_PMb717ZZTX71D0lQAXrkptdRNsBZ_4i/s320/blogger-image1.png" style="
display: none;"/>
# **概要**
Google SpreadSheetで表を作ってBloggerに貼り付けると、表のデザインがそのままBloggerで再現できるので、表の貼り付けにはずっとこの方法を使ってきた。
このままで不自由はなかったが、Jetthemeのxmlをカスタマイズしているついでに、SpreadSheet書式の表からHTML標準表書式の表に変換するスクリプトを作りたくなった。
<a name="more"></a>
## 変換スクリプトでの変換前/変換後比較
preadSheetはセルごとにスタイルやセル幅、フォント他のデザイン情報を定義するので、とても長い記述になる。
### Case1
#### 変換前
<pre class="line-numbers" data-start="1" style="white-space: pre-wrap;"><code class="language-html"><google-sheets-html-origin><table border="1" cellpadding="0" cellspacing="0" data-sheets-baot="1" data-sheets-root="1" dir="ltr" style="border-collapse: collapse; border: none; font-family: Arial; font-size: 10pt; table-layout: fixed; width: 0px;" xmlns="http://www.w3.org/1999/xhtml"><colgroup><col width="122"></col><col width="122"></col></colgroup><tbody><tr style="height: 21px;"><td style="background-color: #efefef; border: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Vactrol</td><td style="background-color: #efefef; border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">購入先</td></tr><tr style="height: 21px;"><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">LCR0203</td><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">秋月</td></tr><tr style="height: 21px;"><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; overflow: hidden; padding: 2px 3px; vertical-align: bottom;"></td><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Aliexpress</td></tr><tr style="height: 21px;"><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">LCR0202</td><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Aliexpress</td></tr><tr style="height: 21px;"><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">VTL5C3</td><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Aliexpress</td></tr></tbody></table></google-sheets-html-origin>
</code></pre></div>
<google-sheets-html-origin><table border="1" cellpadding="0" cellspacing="0" data-sheets-baot="1" data-sheets-root="1" dir="ltr" style="border-collapse: collapse; border: none; font-family: Arial; font-size: 10pt; table-layout: fixed; width: 0px;" xmlns="http://www.w3.org/1999/xhtml"><colgroup><col width="122"></col><col width="122"></col></colgroup><tbody><tr style="height: 21px;"><td style="background-color: #efefef; border: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Vactrol</td><td style="background-color: #efefef; border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">購入先</td></tr><tr style="height: 21px;"><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">LCR0203</td><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">秋月</td></tr><tr style="height: 21px;"><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; overflow: hidden; padding: 2px 3px; vertical-align: bottom;"></td><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Aliexpress</td></tr><tr style="height: 21px;"><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">LCR0202</td><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Aliexpress</td></tr><tr style="height: 21px;"><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">VTL5C3</td><td style="border-color: rgb(204, 204, 204) rgb(0, 0, 0) rgb(0, 0, 0) rgb(204, 204, 204); border-image: initial; border-style: solid; border-width: 1px; font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Aliexpress</td></tr></tbody></table></google-sheets-html-origin>
#### 変換後
<pre class="line-numbers" data-start="1" style="white-space: pre-wrap;"><code class="language-html"><google-sheets-html-origin><table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; width: auto;"><colgroup><col style="width: 70px;"/><col style="width: 100px;"/></colgroup><thead><tr><th>Vactrol</th><th>購入先</th></tr></thead><tbody><tr><td>LCR0203</td><td>秋月</td></tr><tr><td></td><td>Aliexpress</td></tr><tr><td>LCR0202</td><td>Aliexpress</td></tr><tr><td>VTL5C3</td><td>Aliexpress</td></tr></tbody></table></google-sheets-html-origin>
</code></pre>
<google-sheets-html-origin><table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; width: auto;"><colgroup><col style="width: 70px;"/><col style="width: 100px;"/></colgroup><thead><tr><th>Vactrol</th><th>購入先</th></tr></thead><tbody><tr><td>LCR0203</td><td>秋月</td></tr><tr><td></td><td>Aliexpress</td></tr><tr><td>LCR0202</td><td>Aliexpress</td></tr><tr><td>VTL5C3</td><td>Aliexpress</td></tr></tbody></table></google-sheets-html-origin>
### Case2
#### 変換前
<google-sheets-html-origin><table cellpadding="0" cellspacing="0" data-sheets-baot="1" data-sheets-root="1" dir="ltr" style="font-family: Arial; font-size: 10pt; table-layout: fixed; width: 0px;" xmlns="http://www.w3.org/1999/xhtml"><colgroup><col width="124"></col><col width="124"></col><col width="222"></col><col width="210"></col></colgroup><tbody><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); overflow: hidden; padding: 2px 3px; vertical-align: bottom;"></td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); overflow: hidden; padding: 2px 3px; vertical-align: bottom;"></td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); border-top: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow-wrap: break-word; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Turn-on to 63%<br />Final RON (Typ.)</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); border-top: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow-wrap: break-word; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">Turn-off (Decay)<br />to 100 k? (Max.)</td></tr><tr style="height: 21px;"><td colspan="1" rowspan="5" style="border-bottom: 1px solid rgb(0, 0, 0); border-left: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: middle;"><div style="max-height: 105px;">LCR0203</div></td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Datasheet</td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">< 2.5ms</td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">?</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.1</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">8.6us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">119ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.2</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">14.4us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">281ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.3</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">9.2us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">155ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.4</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">12.8us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">185ms</td></tr><tr style="height: 21px;"><td colspan="1" rowspan="6" style="border-bottom: 1px solid rgb(0, 0, 0); border-left: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: middle;"><div style="max-height: 126px;">LCR0202</div></td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Datasheet</td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px##3px; text-align: center; vertical-align: bottom;">< 2.5ms</td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">?</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.1</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">32.8us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">280ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.2</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">13.1us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">280ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.3</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">x</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">x</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.4</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">17.4us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">216ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.5</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">11.1us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">340ms</td></tr><tr style="height: 21px;"><td colspan="1" rowspan="6" style="border-bottom: 1px solid rgb(0, 0, 0); border-left: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: middle;"><div style="max-height: 126px;">VTL5C3</div></td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Datasheet</td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">2.5ms</td><td style="background-color: #e0f7fa; border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">35ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.1</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">10.7us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">211ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.2</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">13.5us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">174ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.3</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">7.1us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">240ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.4</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">9.5us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">322ms</td></tr><tr style="height: 21px;"><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; vertical-align: bottom;">Sample No.5</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">8.3us</td><td style="border-bottom: 1px solid rgb(0, 0, 0); border-right: 1px solid rgb(0, 0, 0); font-size: 14pt; overflow: hidden; padding: 2px 3px; text-align: center; vertical-align: bottom;">322ms</td></tr></tbody></table></google-sheets-html-origin>
#### 変換後
<google-sheets-html-origin><table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; width: auto;"><colgroup><col style="width: 80px;"/><col style="width: 120px;"/><col style="width: 150px;"/><col style="width: 160px;"/></colgroup><thead><tr><th></th><th></th><th>Turn-on to 63%<br>Final RON (Typ.)</th><th>Turn-off (Decay)<br>to 100 k? (Max.)</th></tr></thead><tbody><tr><td colspan="1" rowspan="5">LCR0203</td><td>Datasheet</td><td>< 2.5ms</td><td>?</td></tr><tr><td>Sample No.1</td><td>8.6us</td><td>119ms</td></tr><tr><td>Sample No.2</td><td>14.4us</td><td>281ms</td></tr><tr><td>Sample No.3</td><td>9.2us</td><td>155ms</td></tr><tr><td>Sample No.4</td><td>12.8us</td><td>185ms</td></tr><tr><td colspan="1" rowspan="6">LCR0202</td><td>Datasheet</td><td>< 2.5ms</td><td>?</td></tr><tr><td>Sample No.1</td><td>32.8us</td><td>280ms</td></tr><tr><td>Sample No.2</td><td>13.1us</td><td>280ms</td></tr><tr><td>Sample No.3</td><td>x</td><td>x</td></tr><tr><td>Sample No.4</td><td>17.4us</td><td>216ms</td></tr><tr><td>Sample No.5</td><td>11.1us</td><td>340ms</td></tr><tr><td colspan="1" rowspan="6">VTL5C3</td><td>Datasheet</td><td>2.5ms</td><td>35ms</td></tr><tr><td>Sample No.1</td><td>10.7us</td><td>211ms</td></tr><tr><td>Sample No.2</td><td>13.5us</td><td>174ms</td></tr><tr><td>Sample No.3</td><td>7.1us</td><td>240ms</td></tr><tr><td>Sample No.4</td><td>9.5us</td><td>322ms</td></tr><tr><td>Sample No.5</td><td>8.3us</td><td>322ms</td></tr></tbody></table></google-sheets-html-origin>
## 仕様、使い方
1. pythonで変換スクリプトをつくる。
2. HTMLファイル内の全ての表を標準的な形式に変換し、元の表と置き換える。テーブル以外のコードは変更しない。
3. 変換ファイル名は:conv_table.py`、インプットファイル名:`input.html`, アウトプットファイル名:`output.html`とする。
4. 実行は、`python conv_table.py` とする。
5. 表やセルの装飾はすべて削除し、シンプルは表の書式にする。
6. 1行目をTHEADとする。TBODYの1列目をTHとする。
## Pythonスクリプト
このスクリプトは、<img alt="Google Gemini Logo" height="32" src="https://upload.wikimedia.org/wikipedia/commons/8/8a/Google_Gemini_logo.svg" style="display: inline-block; vertical-align: baseline;" width="75" /> とのやり取りで完成させた。
```python
import sys
from bs4 import BeautifulSoup
def convert_table(html_content):
soup = BeautifulSoup(html_content, 'html.parser')
for table in soup.find_all('table'):
new_table = soup.new_tag('table', border="1", cellpadding="5", cellspacing="0", style="border-collapse: collapse; width: auto;")
thead = soup.new_tag('thead')
tbody = soup.new_tag('tbody')
colgroup = soup.new_tag('colgroup')
rows = table.find_all('tr')
if not rows:
table.replace_with(new_table)
continue
# Determine column widths based on all rows, considering colspan
col_widths = {}
num_cols = 0
for row in rows:
cells = row.find_all('td') + row.find_all('th')
current_col = 0
for cell in cells:
colspan = int(cell.get('colspan', 1))
text_length = len(cell.get_text(strip=True))
for c in range(current_col, current_col + colspan):
col_widths[c] = max(col_widths.get(c, 0), text_length)
current_col += colspan
num_cols = max(num_cols, current_col)
# Apply calculated widths using <colgroup> and <col>
for i in range(num_cols):
width = col_widths.get(i, 5) * 10
col = soup.new_tag('col', style=f"width: {width}px;")
colgroup.append(col)
new_table.insert(0, colgroup)
# Create THEAD
first_row = rows[0]
thead_row = soup.new_tag('tr')
current_col = 0
for cell in first_row.find_all('td') + first_row.find_all('th'):
th_content = cell.get_text(strip=True)
th = soup.new_tag('th')
if 'colspan' in cell.attrs:
th['colspan'] = cell['colspan']
current_col += int(cell['colspan'])
else:
current_col += 1
if 'rowspan' in cell.attrs:
th['rowspan'] = cell['rowspan']
th.string = th_content
thead_row.append(th)
thead.append(thead_row)
new_table.append(thead)
# Create TBODY
for i, row in enumerate(rows[1:]):
tbody_row = soup.new_tag('tr')
cells = row.find_all('td') + row.find_all('th')
for j, cell in enumerate(cells):
if j == 0 and not thead.find('th'):
th = soup.new_tag('th')
th.string = cell.get_text(strip=True)
if 'colspan' in cell.attrs:
th['colspan'] = cell['colspan']
if 'rowspan' in cell.attrs:
th['rowspan'] = cell['rowspan']
tbody_row.append(th)
else:
td = soup.new_tag('td')
td.string = cell.get_text(strip=True)
if 'colspan' in cell.attrs:
td['colspan'] = cell['colspan']
if 'rowspan' in cell.attrs:
td['rowspan'] = cell['rowspan']
tbody_row.append(td)
tbody.append(tbody_row)
new_table.append(tbody)
table.replace_with(new_table)
return str(soup)
if __name__ == "__main__":
input_filename = "input.html"
output_filename = "output.html"
try:
with open(input_filename, 'r', encoding='utf-8') as f:
html_content = f.read()
except FileNotFoundError:
print(f"Error: Input file '{input_filename}' not found.")
sys.exit(1)
converted_html = convert_table(html_content)
try:
with open(output_filename, 'w', encoding='utf-8') as f:
f.write(converted_html)
print(f"Conversion successful. Output written to '{output_filename}'")
except Exception as e:
print(f"Error writing to output file: {e}")
```
## 勘所
改めて、スプレッドシートの表を簡素な表に変換する際の処理の流れをまとめる。
1. **テーブルの抽出**: HTML内から <table> タグを検索し、<google-sheets-html-origin> タグで囲まれたテーブルも抽出する。
1. **標準的なテーブル構造への変換**: 抽出した各テーブルに対して、<thead> と <tbody> を明示的に作成し、最初の行と最初の列をそれぞれ <th> に変換するなど、標準的なHTMLテーブルの構造に整える。
1. **スタイルの調整**: スプレッドシート由来の不要なスタイル属性を削除し、簡素な表示のための基本的なCSSスタイルを適用する。
1. **列幅の調整**: テーブルのコンテンツに基づいて列幅を調整する処理を行う。
注記:<google-sheets-html-origin> タグは、テーブルの抽出時に使用され、変換後もHTML内に残すことにした。ただし、標準の表書式には不要である。
さらに、スクリプトでの作表を繰り返しながら、トライandエラーで
**最初のシンプルなスクリプトから、複雑なテーブル(特にセル結合)や幅の問題に対応できる**ように変換ロジックを以下のように構築した。
1. **列幅決定の進化:**
* **初期:** タイトル行の文字数のみに基づいて列幅を決定していた。
* **最終:** テーブル全体のすべての行のセルの文字数を調べ、各列で最も長い文字数を基準に列幅を決定するようにした。これにより、データ行の長いコンテンツによっても列幅が適切に調整されるようになった。
2. **セル結合 (`colspan`) の考慮:**
* **初期:** セルの結合を考慮せず、単純に列ごとに幅を適用していた。
* **最終:** セルの `colspan` 属性を読み取り、結合されたセルが複数の列にまたがることを考慮して列幅を計算し、`colgroup` を生成するようにした。これにより、結合されたセルを持つテーブルでもレイアウトが崩れにくくなった。
## 関連リンク