当前位置:   article > 正文

python将excel转html的table标签(含合并单元格)_python excel转html

python excel转html

最近在做需求的时候,需要将excel的xlsx文件转为html。

试着找了网上的好多方法,大部分都是table转excel,很少excel转为table标签

如果用pandas库的to_html方法,并不能对合并单元格做有效的处理

目前会读取单元格行高,列宽,字体大小,是否加粗,合并单元格等

如果需要不是你们的需要生成的格式,大家可以在里面加样式就可以

1.读取excel 并 定义相关变量 

  1. import re
  2. from openpyxl import load_workbook
  3. from openpyxl.cell import MergedCell
  4. file=r'你的excel文件路径'
  5. wb=load_workbook(filename=file)
  6. sheet=wb[wb.sheetnames['用于转换的sheet索引页']]
  7. cell_dic= {} #用于储存 所有合并单元格的左上单元格对象
  8. col_width={} #用于储存 所有列的列宽,px
  9. row_height={} #用于储存 所有列的行高,px

2.查询所有列的列宽

  1. #查询列宽
  2. for col in sheet.columns:
  3. pat=r"[A-Z]+"
  4. pat=re.compile(pat)
  5. colname=pat.findall(col[0].coordinate)[0] #分离字母 和数字,取出列字母名称
  6. px=round(sheet.column_dimensions[colname].width*5) #读出列宽换算为像素
  7. col_width[colname]=px

3.查询所有行的行高

  1. #查询行高
  2. for row in sheet.rows:
  3. pat=r"[A-Z]+(\d+)"
  4. pat=re.compile(pat)
  5. rowid=int(pat.findall(row[0].coordinate)[0]) #分离字母 和数字,取出行数字序号
  6. px=sheet.row_dimensions[rowid].height #读出行高换算为像素
  7. if px == None:
  8. px=13.5
  9. row_height[str(rowid)]=px

4.遍历合并的单元区域,找到左上位置的单元格储存在cell_dic字典中,注释很详细

  1. # 找出所有合并区域的行高,列宽,向右合并距离,向下合并距离
  2. for merged_range in sheet.merged_cells.ranges:
  3. now_width=0 #定义列宽
  4. now_height=0 #定义行高
  5. for i in range(merged_range.min_col,merged_range.max_col+1):
  6. coord = sheet.cell(row=1, column=i).coordinate #位置标识,例如:A1
  7. pat = r"[A-Z]+"
  8. pat = re.compile(pat)
  9. colname = pat.findall(coord)[0] # 分离字母 和数字,取出列字母名称
  10. now_width=now_width+col_width[colname]
  11. for i in range(merged_range.min_row, merged_range.max_row + 1):
  12. coord = sheet.cell(row=i, column=1).coordinate # 位置标识,例如:A1
  13. pat = r"[A-Z]+(\d+)"
  14. pat = re.compile(pat)
  15. colindex = pat.findall(coord)[0] # 分离字母 和数字,取出列数字名称
  16. now_height=now_height+row_height[colindex]
  17. now_width=int(now_width) #合并单元格列宽(所有子单元格相加)
  18. now_height=int(now_height) #合并单元格行高(所有子单元格相加)
  19. cell = sheet.cell(row=merged_range.min_row, column=merged_range.min_col) # 选择合并区域左上单元格
  20. colspan = merged_range.max_col - merged_range.min_col + 1 #向右合并长度
  21. rowspan = merged_range.max_row - merged_range.min_row + 1 #向下合并长度
  22. cell_dic[cell]=(now_height,now_width,colspan,rowspan)

5. 这里先定义一个table标签头,不懂的可以去学下html 的table标签

html='''<table border="1">'''

6.这块主要就是拼接html了

  1. #开始写入数据到table标签
  2. for row in sheet.rows:
  3. tr='''<tr>'''
  4. for cell in row:
  5. td=""
  6. if cell in cell_dic: #判断是否为合并单元格左上单元格
  7. if cell.value == None:
  8. text=''
  9. else:
  10. text=cell.value
  11. if cell.alignment.vertical != None:
  12. vertical =f'''vertical-align: {cell.alignment.vertical};''' # 水平位置
  13. else:
  14. vertical = ''
  15. if cell.alignment.horizontal != None:
  16. horizontal = f'''text-align: {cell.alignment.horizontal};''' # 垂直位置
  17. else:
  18. horizontal = ''
  19. font_size=str(int(cell.font.size)+3) #字体大小
  20. font_weight='700' if cell.font.b else '400' #字体是否加粗
  21. style=f'''"color: rgb(0, 0, 0); font-size: {font_size}px; font-weight: {font_weight}; font-style: normal;{vertical}{horizontal}"'''
  22. td = f'''<td height="{cell_dic[cell][0]}" width="{cell_dic[cell][1]}" colspan="{cell_dic[cell][2]}" rowspan="{cell_dic[cell][3]}" style={style}>{text}</td>'''
  23. else:
  24. if not isinstance(cell, MergedCell): # 判断该单元格是否为合并单元格
  25. if cell.alignment.vertical != None:
  26. vertical = f'''vertical-align: {cell.alignment.vertical};''' # 水平位置
  27. else:
  28. vertical = ''
  29. if cell.alignment.horizontal != None:
  30. horizontal = f'''text-align: {cell.alignment.horizontal};''' # 垂直位置
  31. else:
  32. horizontal = ''
  33. pat = r"([A-Z]+)(\d+)"
  34. pat = re.compile(pat)
  35. cell_name=pat.findall(cell.coordinate)[0][0]
  36. cell_index = pat.findall(cell.coordinate)[0][1]
  37. font_size=str(int(cell.font.size)+3) #字体大小
  38. font_weight = '700' if cell.font.b else '400' # 字体是否加粗
  39. style = f'''"color: rgb(0, 0, 0); font-size: {font_size}px; font-weight: {font_weight}; font-style: normal;{vertical}{horizontal}"'''
  40. if cell.value != None:
  41. td = f'''<td height="{row_height[cell_index]}" width="{col_width[cell_name]}" style={style} >{cell.value}</td>'''
  42. else:
  43. td = f'''<td height="{row_height[cell_index]}" width="{col_width[cell_name]}"></td>'''
  44. tr=tr+td
  45. tr=tr+'''</tr>'''
  46. html=html+tr

7.再加一个table标签尾巴,写入本地 end

  1. html=html+'''</table>'''
  2. #写入本地
  3. with open(r"写入路径",'w',encoding='utf-8') as f:
  4. f.write(html)

贴出全部代码

  1. import re
  2. from openpyxl import load_workbook
  3. from openpyxl.cell import MergedCell
  4. class to_html():
  5. def __init__(self,file,save_file,sheet_name):
  6. self.file=file #文件路径
  7. self.save_file=save_file #html保存路径
  8. self.sheet_name=sheet_name #sheet名
  9. def creat_html(self):
  10. wb=load_workbook(filename=self.file)
  11. sheet=wb[self.sheet_name]
  12. cell_dic= {} #用于储存 所有合并单元格的左上单元格对象
  13. col_width={} #用于储存 所有列的列宽,px
  14. row_height={} #用于储存 所有列的行高,px
  15. #查询列宽
  16. for col in sheet.columns:
  17. pat=r"[A-Z]+"
  18. pat=re.compile(pat)
  19. colname=pat.findall(col[0].coordinate)[0] #分离字母 和数字,取出列字母名称
  20. px=round(sheet.column_dimensions[colname].width*5) #读出列宽换算为像素
  21. col_width[colname]=px
  22. #查询行高
  23. for row in sheet.rows:
  24. pat=r"[A-Z]+(\d+)"
  25. pat=re.compile(pat)
  26. rowid=int(pat.findall(row[0].coordinate)[0]) #分离字母 和数字,取出行数字序号
  27. px=sheet.row_dimensions[rowid].height #读出行高换算为像素
  28. if px == None:
  29. px=13.5
  30. row_height[str(rowid)]=px
  31. # 找出所有合并区域的行高,列宽,向右合并距离,向下合并距离
  32. for merged_range in sheet.merged_cells.ranges:
  33. now_width=0 #定义列宽
  34. now_height=0 #定义行高
  35. for i in range(merged_range.min_col,merged_range.max_col+1):
  36. coord = sheet.cell(row=1, column=i).coordinate #位置标识,例如:A1
  37. pat = r"[A-Z]+"
  38. pat = re.compile(pat)
  39. colname = pat.findall(coord)[0] # 分离字母 和数字,取出列字母名称
  40. now_width=now_width+col_width[colname]
  41. for i in range(merged_range.min_row, merged_range.max_row + 1):
  42. coord = sheet.cell(row=i, column=1).coordinate # 位置标识,例如:A1
  43. pat = r"[A-Z]+(\d+)"
  44. pat = re.compile(pat)
  45. colindex = pat.findall(coord)[0] # 分离字母 和数字,取出列数字名称
  46. now_height=now_height+row_height[colindex]
  47. now_width=int(now_width) #合并单元格列宽(所有子单元格相加)
  48. now_height=int(now_height) #合并单元格行高(所有子单元格相加)
  49. cell = sheet.cell(row=merged_range.min_row, column=merged_range.min_col) # 选择合并区域左上单元格
  50. colspan = merged_range.max_col - merged_range.min_col + 1 #向右合并长度
  51. rowspan = merged_range.max_row - merged_range.min_row + 1 #向下合并长度
  52. cell_dic[cell]=(now_height,now_width,colspan,rowspan)
  53. html='''<table border="1">'''
  54. #开始写入数据到table标签
  55. for row in sheet.rows:
  56. tr='''<tr>'''
  57. for cell in row:
  58. td=""
  59. if cell in cell_dic: #判断是否为合并单元格左上单元格
  60. if cell.value == None:
  61. text=''
  62. else:
  63. text=cell.value
  64. if cell.alignment.vertical != None:
  65. vertical =f'''vertical-align: {cell.alignment.vertical};''' # 水平位置
  66. else:
  67. vertical = ''
  68. if cell.alignment.horizontal != None:
  69. horizontal = f'''text-align: {cell.alignment.horizontal};''' # 垂直位置
  70. else:
  71. horizontal = ''
  72. font_size=str(int(cell.font.size)+3) #字体大小
  73. font_weight='700' if cell.font.b else '400' #字体是否加粗
  74. style=f'''"color: rgb(0, 0, 0); font-size: {font_size}px; font-weight: {font_weight}; font-style: normal;{vertical}{horizontal}"'''
  75. td = f'''<td height="{cell_dic[cell][0]}" width="{cell_dic[cell][1]}" colspan="{cell_dic[cell][2]}" rowspan="{cell_dic[cell][3]}" style={style}>{text}</td>'''
  76. else:
  77. if not isinstance(cell, MergedCell): # 判断该单元格是否为合并单元格
  78. if cell.alignment.vertical != None:
  79. vertical = f'''vertical-align: {cell.alignment.vertical};''' # 水平位置
  80. else:
  81. vertical = ''
  82. if cell.alignment.horizontal != None:
  83. horizontal = f'''text-align: {cell.alignment.horizontal};''' # 垂直位置
  84. else:
  85. horizontal = ''
  86. pat = r"([A-Z]+)(\d+)"
  87. pat = re.compile(pat)
  88. cell_name=pat.findall(cell.coordinate)[0][0]
  89. cell_index = pat.findall(cell.coordinate)[0][1]
  90. font_size=str(int(cell.font.size)+3) #字体大小
  91. font_weight = '700' if cell.font.b else '400' # 字体是否加粗
  92. style = f'''"color: rgb(0, 0, 0); font-size: {font_size}px; font-weight: {font_weight}; font-style: normal;{vertical}{horizontal}"'''
  93. if cell.value != None:
  94. td = f'''<td height="{row_height[cell_index]}" width="{col_width[cell_name]}" style={style} >{cell.value}</td>'''
  95. else:
  96. td = f'''<td height="{row_height[cell_index]}" width="{col_width[cell_name]}"></td>'''
  97. tr=tr+td
  98. tr=tr+'''</tr>'''
  99. html=html+tr
  100. html=html+'''</table>'''
  101. with open(self.save_file,'w',encoding='utf-8') as f:
  102. f.write(html)
  103. if __name__=='__main__':
  104. data=to_html("D:\\test.xlsx","D:\\test.html","测试sheet")
  105. data.creat_html()

测试图

生成的html源代码

  1. <table border="1">
  2. <tr>
  3. <td height="13" width="195" colspan="3" rowspan="1" style="color: rgb(0, 0, 0); font-size: 14px; font-weight: 400; font-style: normal;vertical-align: center;text-align: center;">合并单元格</td>
  4. </tr>
  5. <tr>
  6. <td height="18.75" width="65" style="color: rgb(0, 0, 0); font-size: 14px; font-weight: 700; font-style: normal;vertical-align: center;">加粗</td>
  7. <td height="18.75" width="65" style="color: rgb(0, 0, 0); font-size: 17px; font-weight: 400; font-style: normal;vertical-align: center;">宋体</td>
  8. <td height="18.75" width="65">
  9. </td>
  10. </tr>
  11. <tr>
  12. <td height="27" width="130" colspan="2" rowspan="2" style="color: rgb(0, 0, 0); font-size: 21px; font-weight: 400; font-style: normal;vertical-align: center;text-align: center;">合并单元格</td>
  13. <td height="13.5" width="65" style="color: rgb(0, 0, 0); font-size: 14px; font-weight: 400; font-style: normal;vertical-align: center;text-align: center;">居中</td>
  14. </tr>
  15. <tr>
  16. <td height="13.5" width="65" style="color: rgb(0, 0, 0); font-size: 14px; font-weight: 400; font-style: normal;vertical-align: center;text-align: right;">靠右</td>
  17. </tr>
  18. </table>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/249971
推荐阅读
相关标签
  

闽ICP备14008679号