def ToHtml(self, columns_order=None, order_by=()):
    table_template = "<html><body><table border=\"1\">%s</table></body></html>"
    columns_template = "<thead><tr>%s</tr></thead>"
    rows_template = "<tbody>%s</tbody>"
    row_template = "<tr>%s</tr>"
    header_cell_template = "<th>%s</th>"
    cell_template = "<td>%s</td>"
    if columns_order is None:
      columns_order = [col["id"] for col in self.__columns]
    col_dict = dict([(col["id"], col) for col in self.__columns])
    columns_list = []
    for col in columns_order:
      columns_list.append(header_cell_template %
                          html.escape(col_dict[col]["label"]))
    columns_html = columns_template % "".join(columns_list)
    rows_list = []
    for row, unused_cp in self._PreparedData(order_by):
      cells_list = []
      for col in columns_order:
        value = ""
        if col in row and row[col] is not None:
          value = self.CoerceValue(row[col], col_dict[col]["type"])
        if isinstance(value, tuple):
          cells_list.append(cell_template % html.escape(self.ToString(value[1])))
        else:
          cells_list.append(cell_template % html.escape(self.ToString(value)))
      rows_list.append(row_template % "".join(cells_list))
    rows_html = rows_template % "".join(rows_list)
    return table_template % (columns_html + rows_html)