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 154 155 156 157
| import os import openpyxl import xlrd import csv
""" 类功能概述: 本代码实现了一个支持读取多种格式(xlsx、xls、csv)Excel 文件的功能。 主要包含 `Workbook` 和 `Sheet` 相关类,提供了统一的接口来操作不同格式文件。
使用步骤: 1. 创建 `Workbook` 对象,传入文件路径,根据文件后缀自动选择合适的解析器。 2. 通过 `Workbook` 对象的 `sheet_by_index` 方法获取指定索引的工作表(`Sheet` 对象)。 3. 使用 `Sheet` 对象的 `cell_value` 方法获取指定单元格的值,`max_row` 方法获取最大行数,`max_col` 方法获取最大列数。 """
class Sheet: """ `Sheet` 类是所有工作表类的基类,定义了获取单元格值、最大行数和最大列数的接口。
方法: cell_value(row, col): 获取指定行和列的单元格值。 max_row(): 获取工作表的最大行数。 max_col(): 获取工作表的最大列数。 """
def cell_value(self, row, col): pass
def max_row(self): pass
def max_col(self): pass
class XlsxSheet(Sheet): def __init__(self, sheet): self.sheet = sheet
def cell_value(self, row, col): return self.sheet.cell(row=row+1, column=col+1).value
def max_row(self): return self.sheet.max_row
def max_col(self): return self.sheet.max_column
class XlsSheet(Sheet): def __init__(self, sheet): self.sheet = sheet
def cell_value(self, row, col): return self.sheet.cell_value(row, col)
def max_row(self): return self.sheet.nrows
def max_col(self): return self.sheet.ncols
class CsvSheet(Sheet): def __init__(self, rows): self.rows = rows
def cell_value(self, row, col): if row < len(self.rows) and col < len(self.rows[row]): return self.rows[row][col] return None
def max_row(self): return len(self.rows)
def max_col(self): max_cols = 0 for row in self.rows: max_cols = max(max_cols, len(row)) return max_cols
class _Workbook: def sheet_by_index(self, index): pass
class XlsxFile(_Workbook): def __init__(self, path): self.workbook = openpyxl.load_workbook(path)
def sheet_by_index(self, index): sheet = self.workbook[self.workbook.sheetnames[index]] return XlsxSheet(sheet)
class XlsFile(_Workbook): def __init__(self, path): self.workbook = xlrd.open_workbook(path)
def sheet_by_index(self, index): sheet = self.workbook.sheet_by_index(index) return XlsSheet(sheet)
class CsvFile(_Workbook): def __init__(self, path): encodings = ['utf-8-sig', 'utf-8'] for encoding in encodings: try: with open(path, 'r', encoding=encoding) as file: reader = csv.reader(file) self.rows = list(reader) break except UnicodeDecodeError: continue else: raise UnicodeDecodeError("无法使用支持的编码读取文件")
def sheet_by_index(self, index): if index == 0: return CsvSheet(self.rows) return None
class Workbook: """ `Workbook` 类是对外提供的工作簿类,根据文件后缀自动选择合适的解析器。
属性: impl: 具体的工作簿实现对象(`XlsxFile`、`XlsFile` 或 `CsvFile`)。
方法: __init__(path): 初始化工作簿对象,根据文件后缀选择合适的解析器。 sheet_by_index(index): 获取指定索引的工作表。 """
def __init__(self, path): filedir, filename = os.path.split(path) _, extname = os.path.splitext(filename) if extname == ".xlsx": self.impl = XlsxFile(path) elif extname == ".xls": self.impl = XlsFile(path) elif extname == ".csv": self.impl = CsvFile(path) else: raise IOError("未知的文件类型")
def sheet_by_index(self, index): return self.impl.sheet_by_index(index)
|