久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

python 封裝openpyxl實現(xiàn)excel讀寫功能

 hdzgx 2020-01-06

說到python讀寫excel,,想到的的就是xlrd,、xlwt,、openpyxl,、pandas這幾個庫吧,,最近用到讀寫excel,于是初略看了下這幾個庫的使用,,xlrd用于讀取excel的,,xlwt用于寫excel的,但不能寫后輟為.xlsx的文件,,openpyxl既能讀也能寫,,感覺是前面兩個的結(jié)合以及結(jié)合,用法也基本雷同,,pandas功能比較強大,,能讀能寫,還能各種數(shù)據(jù)分析,,在excel表格中能操作的,,幾乎在pandas中都能做到。xlrd讀取數(shù)據(jù)時,,可以直接到表格的一行轉(zhuǎn)成一個列表,,比較方便,openpyxl讀來每行是以cell為元素的列表,,還要再轉(zhuǎn)換一次(或許我還不知道怎么直接轉(zhuǎn)成列表的),,所以寫用了xlrd。由于xlwt不能寫.xlsx的文件,,于用寫用openpyxl,,pandas躍然功能強大,但對我來說感覺pandas還是比較復雜,,不好操作,,前兩個已滿足我現(xiàn)在的讀寫的功能需求。不管是xlrd還是openpyxl,讀寫的流程基本是一樣的,,寫初始化一個workbook,,再獲取一個sheet,然后讀或者寫數(shù)據(jù),,如果寫,,還要設置表格的樣式,最后workbook.save()下,。每次都這樣嫌麻煩,,于是想寫兩個方法封裝下。

def readExcel(path, sheetName=None):

第一個讀的方法,,接受一個已存在的Excel路徑,還有一個可選參數(shù)sheetName,,如果不指定,,默認讀第一個表格,返回一個兩層的列表[ [], [] ,....],第二層的列表每一個表示一行的數(shù)據(jù),,得到每行的數(shù)據(jù)后,,想怎么操作就看自己的了。

def writeExcel(path, data, title=None, row_height=18, merge_row_col=[]):

第二個寫的方法

path:寫入excel的文件路徑,,不存在新建,,存在的話就覆蓋

data:寫入excel的數(shù)據(jù),格式為[[], [],...]或([], [],...)或[(), (),...]或((),,( ),...),,第二層每個元素表示一行數(shù)據(jù),可以長度不一致,,表格的列數(shù)以最長的那個元素為準,,值為None或者長度達不到最達長度的,寫入excel時為空

title:表格名稱,,就是我們excel中的sheet1,sheet2,類型為字符串

row_height:設置表格行高,,默認為18,

merge_row_col:合并單元格的起止位置組合,,格式為({},{},...)或[{},{},...],,其中元素{}的key-value如下:

  1. {
  2. "start_row": 2,
  3. "start_column": 4,
  4. "end_row": 3,
  5. "end_column": 4
  6. }

然后這個方法把樣式寫死了,有需求自己改下,,把樣式的值放方法參數(shù)中,,可在外進行設置。

def judge_merge(merge_row_col):

這個方法是判斷傳入的merge_row_col是否符合合并的要求,,要求是兩次合并不能重疊

其他幾個方法是設置表格樣式的,,字體,對齊方式,邊框,,表格寬以該列最長的符的最高為標準來設置,,最小為8,最大為38,,若列寬需要寬度大于38,,則自動縮小文字至適應。

      

  1. import xlrd
  2. import openpyxl as xl
  3. from openpyxl.styles import Alignment, Font, colors, Side, Border
  4. import re
  5. def readExcel(path, sheetName=None):
  6. workbook = xlrd.open_workbook(path)
  7. sheet = workbook.sheet_by_index(0)
  8. if sheetName:
  9. sheet = workbook.sheet_by_name(sheetName)
  10. data = []
  11. for ri in range(sheet.nrows):
  12. row = sheet.row_values(ri)
  13. data.append(row)
  14. return data
  15. def writeExcel(path, data, title=None, row_height=18, merge_row_col=[]):
  16. if not isinstance(data, list) and not isinstance(data, tuple):
  17. raise BaseException("data只能是列表或元組")
  18. if len(data) > 0 and (not isinstance(data[0], list) and not isinstance(data[0], tuple)):
  19. raise BaseException("data只能是列表或元組")
  20. if len(merge_row_col) > 0:
  21. if not isinstance(merge_row_col, tuple) and not isinstance(merge_row_col, list):
  22. raise BaseException("merge_row_col只能是以dict為元素的列表或元組")
  23. elif not isinstance(merge_row_col[0], dict):
  24. raise BaseException("merge_row_col只能是以dict為元素的列表或元組")
  25. if not judge_merge(merge_row_col):
  26. raise BaseException("merge_row_col不符合要求,,不能合并")
  27. workbook = xl.Workbook()
  28. sheet = workbook.active
  29. if title:
  30. sheet = workbook.create_sheet(title=title, index=0)
  31. maxRow = len(data)
  32. maxCol = 0
  33. for row in data:
  34. maxCol = len(row) if maxCol < len(row) else maxCol
  35. sheet.append(row)
  36. col_length = {
  37. }
  38. '''
  39. 合并單元格,放在設置單元格樣式之前,,否則無邊框
  40. '''
  41. for row_col in merge_row_col:
  42. sheet.merge_cells(
  43. start_row=row_col["start_row"],
  44. start_column=row_col["start_column"],
  45. end_row=row_col["end_row"],
  46. end_column=row_col["end_column"]
  47. )
  48. '''
  49. 設置單元格樣式
  50. '''
  51. for r in range(1, maxRow + 1):
  52. sheet.row_dimensions[r].height = row_height
  53. for c in range(1, maxCol + 1):
  54. cell = sheet.cell(row=r, column=c)
  55. # 設置邊框
  56. cell.border = getBorder()
  57. re_hanzi = re.compile(r"[\u4E00-\u9FFF]")
  58. w = len(str(cell.value))
  59. # 有漢字乘以2,否則乘以1.5
  60. if re_hanzi.search(str(cell.value)):
  61. w *= 2
  62. else:
  63. w *= 1.5
  64. # 列寬最小為8,,最大為38,,超過38文字縮小至適合大小
  65. w = 8 if w < 8 else w
  66. if w > 38:
  67. w = 38
  68. cell.alignment = getAlignment(shrink_to_fit=True)
  69. else:
  70. cell.alignment = getAlignment()
  71. if col_length.get(cell.column):
  72. col_length[cell.column] = w if col_length[cell.column] < w else col_length[cell.column]
  73. else:
  74. col_length[cell.column] = w
  75. # 第一行加粗
  76. if r == 1:
  77. cell.font = getFont(bold=True)
  78. else:
  79. cell.font = getFont()
  80. '''
  81. 設置列寬
  82. '''
  83. for key, val in col_length.items():
  84. sheet.column_dimensions[key].width = val + 0.7
  85. workbook.save(path)
  86. '''
  87. 判斷合并單元格是否符合要求
  88. '''
  89. def judge_merge(merge_row_col):
  90. if len(merge_row_col) == 1:
  91. if merge_row_col[0]["start_row"] <= merge_row_col[0]["end_row"] and \
  92. merge_row_col[0]["start_column"] <= merge_row_col[0]["end_column"]:
  93. return True
  94. else:
  95. return False
  96. for i in range(len(merge_row_col)):
  97. tempi = merge_row_col[i]
  98. if not (tempi["start_row"] <= tempi["end_row"] and tempi["start_column"] <= tempi["end_column"]):
  99. return False
  100. if i == len(merge_row_col) - 1:
  101. break
  102. for j in range(i + 1, len(merge_row_col)):
  103. tempj = merge_row_col[j]
  104. if not (tempj["start_column"] > tempi["end_column"] or \
  105. tempj["end_column"] < tempi["start_column"] or \
  106. tempj["start_row"] > tempi["end_row"] or \
  107. tempj["end_row"] < tempi["start_row"]):
  108. return False
  109. return True
  110. def getAlignment(horizontal='center', vertical='center', shrink_to_fit=False, wrap_text=False, text_rotation=0,
  111. indent=0):
  112. agt = Alignment(
  113. horizontal=horizontal,
  114. vertical=vertical,
  115. shrink_to_fit=shrink_to_fit,
  116. wrap_text=wrap_text,
  117. text_rotation=text_rotation,
  118. indent=indent
  119. )
  120. return agt
  121. def getFont(name='宋體', size=12, bold=False, italic=False, vertAlign=None, underline=None, strike=False,
  122. color=colors.BLACK):
  123. font = Font(
  124. name=name,
  125. size=size,
  126. bold=bold,
  127. italic=italic,
  128. vertAlign=vertAlign,
  129. underline=underline,
  130. strike=strike,
  131. color=color
  132. )
  133. return font
  134. '''
  135. style的值為:
  136. {'double', 'dashDot', 'mediumDashDot', 'dotted', 'medium', 'thick', 'dashDotDot', 'thin',
  137. 'mediumDashDotDot', 'mediumDashed', 'slantDashDot', 'dashed', 'hair'}
  138. '''
  139. def getBorder():
  140. border = Border(
  141. left=Side(style='thin', color='FF000000'),
  142. right=Side(style='thin', color='FF000000'),
  143. top=Side(style='thin', color='FF000000'),
  144. bottom=Side(style='thin', color='FF000000')
  145. )
  146. return border

測試:

  1. if __name__ == "__main__":
  2. data = (
  3. ["ID", "name", "age", "createDate", "title1", "title2"],
  4. [1, "楊", 23, "2018-12-09","rewf0"],
  5. [2, "張", 33, "2018-12-09", None, "很長很長的中文文字很長很長的中文文字很長很長的中文文字很長很長的中文文字",],
  6. [3, "王", 42, "2018-12-10","長中文文字長中文文字長中文文字長中文文字"]
  7. )
  8. merge_row_col = (
  9. {
  10. "start_row": 2,
  11. "start_column": 4,
  12. "end_row": 3,
  13. "end_column": 4
  14. },
  15. )
  16. writeExcel(path=r"C:\Users\dpyang\Desktop\temp\test.xlsx", data=data, merge_row_col=merge_row_col)

 

寫入結(jié)果:

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約