python 使用Python生成包含表格,图像和段落的HTML格式文件。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 使用Python生成包含表格,图像和段落的HTML格式文件。相关的知识,希望对你有一定的参考价值。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This module provides a few classes to easily generate HTML code
for tables, images and paragraphs.
"""

__version__ = '0.2'
__date__ = '2016-04-13'
__author__ = 'Guangning Yu'


class TableCell():

    def __init__(self, text="", bgcolor=None, width=None, height=None,
                 align=None, valign=None, char=None, charoff=None,
                 header=None, colspan=None, rowspan=None, hidden=False,
                 padding_left=5, padding_right=5, color=None, font_weight=None):
        """TableCell constructor"""
        self.text    = text
        self.orig_value = text
        # cell attributes
        self.bgcolor = bgcolor
        self.width   = width
        self.height  = height
        self.align   = align
        self.valign  = valign
        self.char    = char
        self.charoff = charoff
        self.colspan = colspan
        self.rowspan = rowspan
        # style
        self.color   = color
        self.padding_left  = padding_left
        self.padding_right = padding_right
        self.font_weight   = font_weight
        # custom attributes
        self.header  = header
        self.hidden  = hidden
        self.attr    = {}

    def set_font_color(self, color_nm):
        self.color = get_color(color_nm)
        return self

    def set_bg_color(self, color_nm):
        self.bgcolor = get_color(color_nm)
        return self

    def set_bold(self):
        self.font_weight = 'bold'
        return self

    def __str__(self):
        """return the HTML code for the table cell"""
        # deal with the attributes
        if self.bgcolor: self.attr['bgcolor'] = self.bgcolor
        if self.width:   self.attr['width']   = self.width
        if self.height:  self.attr['height']  = self.height
        if self.align:   self.attr['align']   = self.align
        if self.valign:  self.attr['valign']  = self.valign
        if self.char:    self.attr['char']    = self.char
        if self.charoff: self.attr['charoff'] = self.charoff
        if self.colspan: self.attr['colspan'] = self.colspan
        if self.rowspan: self.attr['rowspan'] = self.rowspan

        self.attr['style'] = 'padding-left: %spx; padding-right: %spx' % (self.padding_left, self.padding_right)
        if self.color:   self.attr['style'] += '; color: %s' % self.color
        if self.font_weight: self.attr['style'] += '; font-weight: %s' % self.font_weight

        attr_str = ""
        for attr in self.attr.keys():
            attr_str += ' %s="%s"' % (attr, self.attr[attr])
        # deal with the content text
        if self.text:
            text = str(self.text)
        else:
            text = " "
        # return the HTML code
        if not self.hidden:
            if self.header:
                return '    <TH%s>%s</TH>\n' % (attr_str, text)
            else:
                return '    <TD%s>%s</TD>\n' % (attr_str, text)
        else:
            return ''


class TableRow():

    def __init__(self, cells=None):
        """TableRow constructor"""
        self.cells = [TableCell(cell) if not isinstance(cell, TableCell) else cell for cell in cells]

    def __str__(self):
        """return the HTML code for the table row"""
        result = ""
        result += '<TR>\n'
        for cell in self.cells:
            result += str(cell)
        result += '</TR>\n'
        return result


class Table():

    def __init__(self, rows=None, width="800", border="1", cellspacing="0", cellpadding=None,
                 font_family="微软雅黑", font_size="11px", table_border="1px solid #000000", border_collapse="collapse"):
        """Table constructor"""
        self.rows = [TableRow(row) if not isinstance(row, TableRow) else row for row in rows]
        # table attributes
        self.width           = width
        self.border          = border
        self.cellspacing     = cellspacing
        self.cellpadding     = cellpadding
        # style attributes
        self.font_family     = font_family
        self.font_size       = font_size
        self.table_border    = table_border
        self.border_collapse = border_collapse
        # init attribute dict
        self.attr = {}

    def get_cells(self, rows_idx=None, cols_idx=None):
        cell_list = []
        if rows_idx:
            rows_idx = [int(i)-1 for i in str(rows_idx).strip().split(',')]
        if cols_idx:
            cols_idx = [int(i)-1 for i in str(cols_idx).strip().split(',')]
        for row in self.rows:
            for cell in row.cells:
                row_idx = self.rows.index(row)
                col_idx = row.cells.index(cell)
                if rows_idx and cols_idx == None:
                    if row_idx in rows_idx:
                        cell_list.append(cell)
                elif rows_idx == None and cols_idx:
                    if col_idx in cols_idx:
                        cell_list.append(cell)
                elif rows_idx and cols_idx:
                    if row_idx in rows_idx and col_idx in cols_idx:
                        cell_list.append(cell)
        return cell_list

    def get_all_cells(self):
        cell_list = []
        for row in self.rows:
            for cell in row.cells:
                cell_list.append(cell)
        return cell_list

    def set_row_header(self, rows_idx):
        for cell in self.get_cells(rows_idx=rows_idx):
            cell.header = True
        return self

    def set_color(self, rows_idx=None, cols_idx=None, color_nm=None):
        for cell in self.get_cells(rows_idx=rows_idx, cols_idx=cols_idx):
            cell.bgcolor = get_color(color_nm)
        return self

    def set_hidden(self, rows_idx=None, cols_idx=None):
        for cell in self.get_cells(rows_idx=rows_idx, cols_idx=cols_idx):
            cell.hidden = True
        return self

    def set_row_color(self, rows_idx, color_nm):
        return self.set_color(rows_idx=rows_idx, cols_idx=None, color_nm=color_nm)

    def set_row_bold(self, rows_idx):
        for cell in self.get_cells(rows_idx=rows_idx):
            cell.font_weight = 'bold'
        return self

    def set_row_font_color(self, rows_idx, color_nm):
        for cell in self.get_cells(rows_idx=rows_idx):
            cell.color = get_color(color_nm)
        return self

    def set_pct(self, rows_idx=None, cols_idx=None, num_digits=2):
        for cell in self.get_cells(rows_idx=rows_idx, cols_idx=cols_idx):
            if not cell.header:
                try:
                    formatter = '.' + str(num_digits) + 'f'
                    format_text = format(float(cell.orig_value)*100, formatter)
                    cell.text = format_text + '%'
                except Exception as e:
                    continue
        return self

    def set_num(self, rows_idx=None, cols_idx=None, num_digits=0):
        for cell in self.get_cells(rows_idx=rows_idx, cols_idx=cols_idx):
            if not cell.header:
                try:
                    formatter = '.' + str(num_digits) + 'f'
                    format_text = format(float(cell.orig_value), formatter)
                    dig = format_text.split('.')[0]
                    cell.text = '{:,}'.format(int(dig))
                    try:
                        dec = format_text.split('.')[1]
                        cell.text += '.%s' % dec
                    except Exception as e:
                        next
                except Exception as e:
                    continue
        return self

    def set_col_pct(self, cols_idx, num_digits=2):
        return self.set_pct(rows_idx=None, cols_idx=cols_idx, num_digits=num_digits)

    def set_col_num(self, cols_idx, num_digits=0):
        return self.set_num(rows_idx=None, cols_idx=cols_idx, num_digits=num_digits)

    def set_col_align_left(self, cols_idx):
        for cell in self.get_cells(cols_idx=cols_idx):
            if not cell.header:
                cell.align = 'left'
        return self

    def set_col_align_right(self, cols_idx):
        for cell in self.get_cells(cols_idx=cols_idx):
            if not cell.header:
                cell.align = 'right'
        return self

    def set_row_align_right(self, rows_idx):
        for cell in self.get_cells(rows_idx=rows_idx):
            if not cell.header:
                cell.align = 'right'
        return self

    def set_col_align_center(self, cols_idx):
        for cell in self.get_cells(cols_idx=cols_idx):
            if not cell.header:
                cell.align = 'center'
        return self

    def set_scale(self, rows_idx=None, cols_idx=None, scale=1):
        for cell in self.get_cells(rows_idx=rows_idx, cols_idx=cols_idx):
            if not cell.header:
                try:
                    cell.orig_value = str(float(cell.orig_value)/float(scale))
                except Exception as e:
                    continue
        return self

    def set_col_scale(self, cols_idx, scale):
        return self.set_scale(rows_idx=None, cols_idx=cols_idx, scale=scale)

    def set_col_format_blank(self, cols_idx, format=' - '):
        for cell in self.get_cells(cols_idx=cols_idx):
            if not cell.header:
                try:
                    if float(cell.orig_value) == 0:
                        cell.text = format
                except Exception as e:
                    continue
        return self


    def set_col_sort(self, cols_idx, sort_order=None):
        if sort_order:
            col_idx = cols_idx - 1
            items = sort_order.strip().replace(";",",").split(',')
            new_rows = []
            # 1.add headers
            for row in self.rows:
                if row.cells[0].header:
                    new_rows.append(row)
                    row.drop = True
                else:
                    row.drop = False
            self.rows = [row for row in self.rows if not row.drop]
            # 2.add rows that need to be sorted
            for item in items:
                for row in self.rows:
                    if row.cells[col_idx].text == item:
                        new_rows.append(row)
                        row.drop = True
                    else:
                        row.drop = False
                self.rows = [row for row in self.rows if not row.drop]
            # 3.add the left rows
            for row in self.rows:
                new_rows.append(row)
            # 4.return the sorted rows
            self.rows = new_rows
            return self
        return self

    def set_rowspan(self, tgt_row_idx, tgt_col_idx, rowspan):
        tgt_row_idx = int(tgt_row_idx) - 1
        tgt_col_idx = int(tgt_col_idx) - 1
        for row in self.rows:
            for cell in row.cells:
                row_idx = self.rows.index(row)
                col_idx = row.cells.index(cell)
                if row_idx == tgt_row_idx and col_idx == tgt_col_idx:
                    cell.rowspan = rowspan
                elif row_idx > tgt_row_idx and row_idx < tgt_row_idx + int(rowspan) and col_idx == tgt_col_idx:
                    cell.hidden = True
        return self

    def set_colspan(self, tgt_row_idx, tgt_col_idx, colspan):
        tgt_row_idx = int(tgt_row_idx) - 1
        tgt_col_idx = int(tgt_col_idx) - 1
        for row in self.rows:
            for cell in row.cells:
                row_idx = self.rows.index(row)
                col_idx = row.cells.index(cell)
                if row_idx == tgt_row_idx and col_idx == tgt_col_idx:
                    cell.colspan = colspan
                elif row_idx == tgt_row_idx and col_idx > tgt_col_idx and col_idx < tgt_col_idx + int(colspan):
                    cell.hidden = True
        return self

    def set_width(self, width):
        self.width = str(width)
        return self

    def set_font_size(self, size):
        self.font_size = size
        return self

    def __str__(self):
        """return the HTML code for the table"""
        result = ""
        # deal with the table attributes
        if self.width:       self.attr['width']       = self.width
        if self.border:      self.attr['border']       = self.border
        if self.cellspacing: self.attr['cellspacing'] = self.cellspacing
        if self.cellpadding: self.attr['cellpadding'] = self.cellpadding
        self.attr['style'] = 'font-family:%s; font-size:%s; border:%s; border-collapse:%s' % (self.font_family, self.font_size, self.table_border, self.border_collapse)
        attr_str = ""
        for attr in self.attr.keys():
            attr_str += ' %s="%s"' % (attr, self.attr[attr])
        result += '<TABLE%s>\n' % attr_str
        # apply the row attributes
        for row in self.rows:
            result += str(row)
        # end of the table
        result += '</TABLE>'
        result += '<BR>'
        return result


class Paragraph():

    def __init__(self, text="", color="#000000", font_family="微软雅黑", font_style="normal",
                 font_size="11", font_weight="normal", margin="3", align="left"):
        """Paragraph constructor"""
        self.text        = text
        self.color       = color
        self.font_family = font_family
        self.font_style  = font_style
        self.font_size   = font_size
        self.font_weight = font_weight
        self.margin      = margin
        self.align       = align

    def set_color(self, color):
        self.color = get_color(color)
        return self

    def set_align(self, align):
        self.align = align
        return self

    def set_bold(self):
        self.font_weight = 'bold'
        return self

    def set_italic(self):
        self.font_style = 'italic'
        return self

    def set_font_size(self, size):
        self.font_size = size
        return self

    def __str__(self):
        """return the HTML code for the paragraph"""
        result = ""
        result += '<p style="font-family:%s; color:%s; font-size:%spx; font-weight:%s; font-style:%s; margin:%s" align="%s">\n' % (self.font_family, self.color, self.font_size, self.font_weight, self.font_style, self.margin, self.align)
        for line in self.text:
            line = line.replace(' ','&nbsp;')
            result += '%s<BR>\n' % line
        result += '</p>\n'
        return result


class Image():

    def __init__(self, src=None, alt=None, width=None, height=None, hspace=None, vspace=None):
        """Image constructor"""
        self.src = src.strip().split('/')[-1]
        self.alt = alt if alt else self.src
        self.width = width
        self.height = height
        self.hspace = hspace
        self.vspace = vspace
        self.attr = {}

    def __str__(self):
        """return the HTML code for the image"""
        if self.src:    self.attr['src'] = 'cid:' + self.src
        if self.alt:    self.attr['alt'] = self.alt
        if self.width:  self.attr['width'] = self.width
        if self.height: self.attr['height'] = self.height
        if self.hspace: self.attr['hspace'] = self.hspace
        if self.vspace: self.attr['vspace'] = self.vspace
        attr_str = ""
        for attr in self.attr.keys():
            attr_str += ' %s="%s"' % (attr, self.attr[attr])
        result = ''
        result += '<IMG%s>' % attr_str
        #result += '<BR>\n'
        #result += '<BR>\n'
        return result


def get_color(color):
    color = str(color).upper()
    color_dict = {
        'RED':        '#FF0000'
        ,'ORANGE':    '#FFC000'
        ,'YELLOW':    '#FFFF00'
        ,'GREEN':     '#92D050'
        ,'BLUE':      '#00B0F0'
        ,'PURPLE':    '#8064A2'
        ,'WHITE':     '#FFFFFF'
        ,'BLACK':     '#000000'
        ,'GREY':      '#BFBFBF'
        ,'LIGHTBLUE': '#CAE1FF'
        ,'PINK':      '#FDE4D0'
        }
    if color in color_dict.keys():
        return color_dict[color]
    else:
        return color

以上是关于python 使用Python生成包含表格,图像和段落的HTML格式文件。的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 将文本添加到多个图像

用Keras生成面部Python实现

如何从 Python 中的 HTML / CSS(包括图像)源生成 PDF? [关闭]

浏览pdf文件以查找特定页面并使用python从图像中提取表格数据

Python PDF/图像表重建选项

在 python 脚本中生成带有图像和文本的 html 文档(如果可能,不使用服务器)