1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
| from typing import Optional, Sequence import re import openpyxl from openpyxl.utils import get_column_letter from openpyxl.styles import Alignment, colors, Font, PatternFill, Border, Side
g_mycolor = { 'yellow': '00FFFF00', 'red': '00FF0000', 'blue': '6495ED' }
class Excel(object): def __init__(self, filename) -> None: self.filename = filename
class ExcelRead(Excel): def __init__(self, filename) -> None: super().__init__(filename) self.wb = openpyxl.load_workbook(self.filename)
def read_ws(self, title:str): try: ws = self.wb[title] except: raise KeyError('Sheet not existed!')
return ws
class ExcelWrite(Excel): def __init__(self, filename) -> None: super().__init__(filename) self.wb = openpyxl.Workbook() self.ws_index = 0
def create_ws(self, title): ws = self.wb.create_sheet(index=self.ws_index, title=title) self.ws_index += 1 excel_ws = ExcelWs(ws) return excel_ws
def save(self): self.wb.save(self.filename)
class ExcelWs(object): def __init__(self, ws) -> None: self.index = 1 self.ws = ws self.base_alignment = Alignment(horizontal='center',vertical='center')
def _write(self, row:Sequence, font:Font=None, border:Border=None, fill_color:str=None): for i, item in enumerate(row): self.ws.cell(self.index, i+1).value = item self.ws.cell(self.index, i+1).alignment = self.base_alignment if font: self.set_font(i+1, font) if border: self.set_border(i+1, border) if fill_color: self.set_fill_color(i+1, fill_color)
self.index += 1 return self.index - 1
def write_row(self, row:Sequence): return self._write(row=row, font=Font(name="微软雅黑", size=11), border=Border(left=Side(style='thin'),bottom=Side(style='thin'),right=Side(style='thin'),top=Side(style='thin')) )
def write_title(self, row:Sequence): return self._write(row=row, font=Font(name="微软雅黑", size=11), border=Border(left=Side(style='thin'),bottom=Side(style='thin'),right=Side(style='thin'),top=Side(style='thin')), fill_color='blue' )
def write_row_align_height(self, row:Sequence): height = 1 for i, item in enumerate(row): self.ws.cell(self.index, i+1).value = item self.ws.cell(self.index, i+1).alignment = self.base_alignment if isinstance(item, str): height = item.count('\n') if item.count('\n') > height else height self.ws.row_dimensions[self.index].height = 18 * height self.index += 1 return self.index - 1
def set_border(self, column:int, border:Border): self.ws.cell(self.index, column).border = border
def set_link(self, column:int, link:str): self.ws.cell(self.index, column).hyperlink = link self.set_font(column, Font(color=colors.BLUE, underline='single'))
def set_font(self, column:int, font:Font): self.ws.cell(self.index, column).font = font
def set_color(self, column:int, color:str): self.set_font(column, Font(color=g_mycolor[color]))
def set_fill_color(self, column:int, color:str): self.ws.cell(self.index, column).fill = PatternFill('solid', fgColor=g_mycolor[color])
def merge_cell(self, start_row, start_column, end_row, end_column): self.ws.merge_cells(start_row=start_row, start_column=start_column, end_row=end_row, end_column=end_column)
def align_width(self): dims = {} for row in self.ws.rows: for cell in row: if cell.value: cell_len = 0.9*len(re.findall('([\u4e00-\u9fa5])', str(cell.value))) + 1.2*len(str(cell.value)) dims[cell.column] = max((dims.get(cell.column, 0), cell_len)) for col, value in dims.items(): try: self.ws.column_dimensions[get_column_letter(col)].width = value + 2 except: self.ws.column_dimensions[col].width = value + 2
if __name__ == '__main__': excel_write = ExcelWrite(filename='test.xlsx') ws: ExcelWs = excel_write.create_ws(title='MySheet')
ws.write_title(('姓名', '年龄', '性别', '分数')) ws.write_row(('张三', '16', '男', 85)) ws.write_row(('李四', '17', '男', 80))
excel_write.save()
excel_read = ExcelRead(filename='test.xlsx') rs = excel_read.read_ws(title='MySheet') for row in rs.rows: for item in row: print(item.value, end=' ') print()
|