• Python excel转换为table 主要是合并单元格问题解决


    需求

    我们公司最近又开始搞这些神奇的需求了

    把excel表格 转换为 html里面的table,数量估计有几百个,分了我几十个,尼玛,不想像他们那样一个一个手搓,伤不起。。。
    决定用python解决,后面附上代码
    隔壁那女的更傻,以复制粘贴的多为荣,只想说 呵呵

    代码随便写的几句,一边百度一边写的,主要就是一些逻辑判断罢了





    原始table






    处理后的table






    列的合并处理

    项次1 检验项目3 规定值或允许偏差3 检验结果2 检验方法和频率3 权值1

    因为给的模板的列 实际 他们在html里面画的table的列 数量不对,
    这里需要重新调整过,后面要是有还有很多,可以在程序里面调整



    模板页面

    模板页面主要是定位了几个占位符,替换一下 标题 和 table的核心内容


    @{
        ViewBag.Title = "tmp_title";
        Layout = "~/Views/Shared/_Form.cshtml";
    }
    
    <body>
        <style media="print">
            @@page {
                size: portrait;
                margin-top: 20mm;
                margin-left: 20mm;
                margin-bottom: 15mm;
                margin-right: 15mm;
            }
    
            .no-print {
                display: none !important;
            }
    
            .print-show {
                display: block !important;
            }
            /*@@page {
                    size: landscape;
                    margin-top:20mm;
                    margin-left:15mm;
                    margin-bottom:15mm;
                    margin-right:15mm;
                }*/
    
        </style>
        <style>
            table {
                border-collapse: collapse;
                table-layout: fixed;
                text-align: center;
                margin: 0 auto;
                word-break: break-all;
            }
    
            input {
                 95%;
                height: 95%;
                border: none;
                text-align: center;
                font-size: 16px;
            }
    
            table span {
                display: inline-block;
                font-size: 17px;
            }
    
            textarea {
                 92%;
                height: 92%;
                resize: none;
                border: none;
                font-size: 16px;
                text-align: center;
                overflow: hidden
            }
    
            table tr:not(:nth-child(-n+5)) {
                border-bottom: 1px solid black;
                border-left: 3px solid black;
                border-right: 3px solid black;
            }
    
    
            table tr td {
                height: 30px;
                border-left: 1px solid black;
                border-bottom: none;
                border-top: none;
                font-size: 16px;
            }
    
            input[type=checkbox] {
                 17px;
                height: 17px;
                z-index: -1;
                -webkit-appearance: none;
                outline: none;
            }
    
                input[type=checkbox]:after {
                    height: 100%;
                     100%;
                    top: 0;
                    content: "";
                    /*content:url(../../../../Content/NewTableImg/20200410192843803.png);*/
                    background: white;
                    color: #000000;
                    display: inline-block;
                    visibility: visible;
                    border-radius: 2px;
                    border: 1px solid black;
                }
    
                input[type=checkbox]:checked:after {
                    content: "✓";
                    text-align: center;
                    font-weight: bolder;
                    height: 100%;
                     100%;
                    font-size: 20px;
                    position: relative;
                    line-height: 17px;
                }
        </style>
        <form id="TableList" action="LowVoltageDistributionEquipmentBGD">
            <table id="TableLists" style="800px">
                <tr>
                    <td colspan="13" style="text-align:center; border-top:none;border-right:none;border-left:none;border-bottom:0px solid black;height:35px;line-height:35px;"><input id="Projects" type="text" style="text-align:center;100%;border:none;font-size:19px"></td>
                </tr>
                <tr>
                    <td colspan="13" style=" border:none;text-align:center;height:35px;line-height:35px;">
                        <span style="font-size:23px">
    tmp_title                
                        </span>
                    </td>
                </tr>
                <tr>
                    <td colspan="2" style=" border:none;text-align:right;height:35px;line-height:35px;"><span style="font-weight:500">承包单位:</span></td>
                    <td colspan="5" style=" border:none;border-bottom:1px solid black;height:35px;line-height:35px;"><input id="OrgConstruction" type="text" style="100%;text-align:left;font-weight:500;font-size: 17px;" /></td>
                    <td colspan="2" style=" border:none;height:35px;line-height:35px;"></td>
                    <td colspan="1" style=" border:none;text-align:right;height:35px;line-height:35px;"><span style="font-weight:500">合同号:</span></td>
                    <td colspan="3" style=" border:none;border-bottom:1px solid black;height:35px;line-height:35px;"><input id="ContractCode" type="text" style="100%;text-align:left;font-weight:500;font-size: 17px;" /></td>
                </tr>
                <tr>
                    <td colspan="2" style=" border:none;text-align:right;height:35px;line-height:35px;"> <span style="font-weight:500;">监理单位:</span></td>
                    <td colspan="5" style=" border:none;border-bottom:1px solid black;height:35px;line-height:35px;"><input id="OrgSupervision" type="text" style="100%;text-align:left;font-weight:500;font-size: 17px;" /></td>
                    <td colspan="2" style=" border:none;height:35px;line-height:35px;"></td>
                    <td colspan="1" style=" border:none;text-align:right;height:35px;line-height:35px;"> <span style="font-weight:500">编  号:</span></td>
                    <td colspan="3" style=" border:none;border-bottom:1px solid black;height:35px;line-height:35px;"><input id="Code" type="text" style="100%;text-align:left;font-weight:500;font-size: 17px;" /></td>
                </tr>
                <tr>
                    <td colspan="9" style="border:none;height:35px;line-height:35px;"></td>
                    <td colspan="4" style="100%;text-align:right;border:none;height:35px;line-height:35px;"><span>C-1</span></td>
                </tr>
                <tr style="border-top:3px solid black;height:60px">
                    <td colspan="2">工程名称</td>
                    <td colspan="5" style="white-space:normal;word-break:break-all;"><span class="print-show" style="display:none;"></span><textarea rows="1" class="no-print" id="UseSite" name="UseSite" style="text-align: center;overflow:hidden;word-break: break-all;height:auto;max-height:92%;"></textarea></td>
                    <td colspan="2">施工时间</td>
                    <td colspan="4"><input type="text" id="ConstructionDate" name="ConstructionDate" value="" /></td>
                </tr>
                <tr style="height:60px">
                    <td colspan="2">桩号及部位</td>
                    <td colspan="5" style="white-space:normal;word-break:break-all;"><span class="print-show" style="display:none;"></span><textarea rows="1" class="no-print" id="EngineerName" name="EngineerName" style="text-align: center;overflow:hidden;word-break: break-all;height:auto;max-height:92%;"></textarea></td>
                    <td colspan="2">检验时间</td>
                    <td colspan="4"><input type="text" id="TestDate" name="TestDate" value="" /></td>
                </tr>
                <tr>
                    <td colspan="1" style="text-align:center">项次</td>
                    <td colspan="3" style="text-align:center">检查项目</td>
                    <td colspan="3">规定值或允许偏差</td>
                    <td colspan="2" style="text-align:center">检查结果</td>
                    <td colspan="3" style="text-align:center">检查方法和频率</td>
                    <td colspan="1" style="text-align:center">权值</td>
                </tr>
    
    
    
                <!-- 开始-->
                tmp_content
                <!-- 结束-->
    
    
    
    
                <tr style="border-bottom:none">
                    <td colspan="13" style="text-align: left;border-bottom: none" valign="top">自检结论:</td>
                </tr>
                <tr style="border-top:none">
                    <td colspan="13" style="text-align:center;border-top:none;height:80px">
                        <input id="resut" name="resut" />
                    </td>
                </tr>
                <tr>
                    <td colspan="2">质检负责</td>
                    <td colspan="2">
                        <input type="text" style="text-align:left;border:none" name="ZJFZ" readonly="readonly" id="ZJFZ" value="" />
                    </td>
                    <td colspan="2">检查</td>
                    <td colspan="2">
                        <input type="text" style="text-align:left;border:none" name="JC" readonly="readonly" id="JC" value="" />
                    </td>
                    <td colspan="2">复核</td>
                    <td colspan="3">
                        <input type="text" style="text-align:left;border:none" name="FH" readonly="readonly" id="FH" value="" />
                    </td>
                </tr>
                <tr style="border-bottom:none">
                    <td colspan="13" style="text-align:left;border-bottom:none" valign="top">监理意见:</td>
                </tr>
                <tr style="border-bottom:none;border-top:none;height:60px">
                    <td>
                        <textarea id="opinion" name="opinion"></textarea>
                    </td>
                </tr>
                <tr style="border-top:none;border-bottom:3px solid black">
                    <td colspan="3" style="border:none"></td>
                    <td colspan="3" style="border:none">专业监理工程师:</td>
                    <td colspan="4" style="border:none">
                        <input type="text" style="text-align:left;border:none;height:24px;line-height:24px;" name="JL" readonly="readonly" id="JL" value="" />
                    </td>
                    <td style="border: none;text-align:right"><input type="text" style="100%;text-align:right;height:24px;line-height:24px;" id="Date1" name="Date1" value="" /></td>
                    <td style="border: none;text-align:right"><input type="text" style="100%;text-align:right;height:24px;line-height:24px;" id="Date2" name="Date2" value="" /></td>
                    <td style="border: none;text-align:right"><input type="text" style="100%;text-align:right;height:24px;line-height:24px;" id="Date3" name="Date3" value="" /></td>
                </tr>
    
            </table>
        </form>
    
    </body>
    
    




    控制器方法的生成






    用于记录页面和表对应关系的excel生成

    主要用到了 excel的分列 和 字符串的拼接

    分列

    字符串的拼接
    =CONCATENATE("/NewTable/SurveyReport/",C1)








    python代码

    这些库是之前就安装好的
    后面就安装了一个 xpinyin 这个

    
    import os
    import openpyxl
    from openpyxl import Workbook
    from copy import deepcopy
    from openpyxl.utils import get_column_letter
    from xpinyin import Pinyin
    import re
    
    
    
    workbook2 = Workbook()
    strHtml_tmp = ''
    strTxt_filename = ''
    strTxt_methodname = ''
    
    
    
    def in_area(arr_area, row, col):# 判断是否在区域中
        for area in arr_area:
            if row >= area['r1'] and row <= area['r2'] and col >= area['c1'] and col <= area['c2']:
                #print('in_area')
                #print(area)            
                return area
        #print('not_in_area')
        return None
    
    
    def is_first(area, row, col):# 判断是否是区域的第一个单元格
        min_row = area['r1']  if area['r1'] < area['r2'] else area['r1']
        min_col = area['c1']  if area['c1'] < area['c2'] else area['c2']    
        if row==min_row and col==min_col:
            #print('is_first')
            #print('min_row,min_col', min_row, min_col)    
            return True
        #print('not_first')
        return False
    
    
    p = Pinyin()
    def get_en_name(cn):# 获取英文名    
        en = p.get_initials(cn, '')
        return en
    
    
    
    
    
    
    
    
    
    def read_worksheet(path):
    
        #path='test1.xlsx'
        workbook = openpyxl.load_workbook(path)# 加载excel
        name_list = workbook.sheetnames# 所有sheet的名字
        worksheet = workbook[name_list[0]]# 读取第一个工作表
    
        # 获取所有 合并单元格的 位置信息
        # 是个可迭代对象,单个对象类型:openpyxl.worksheet.cell_range.CellRange
        # print后就是excel坐标信息
        m_list = worksheet.merged_cells
    
        l = deepcopy(m_list)# 深拷贝
        arr_area = []
        
        # 拆分合并的单元格 并填充内容
        for m_area in l:
            # 这里的行和列的起始值(索引),和Excel的一样,从1开始,并不是从0开始(注意)
            r1, r2, c1, c2 = m_area.min_row, m_area.max_row, m_area.min_col, m_area.max_col
            worksheet.unmerge_cells(start_row=r1, end_row=r2, start_column=c1, end_column=c2)
            # print('区域:', m_area, '  坐标:', r1, r2, c1, c2)
            arr_area.append({'r1':r1,'r2':r2,'c1':c1,'c2':c2,'m_area':str(m_area)})        
        
        strHtml = ''    
             
        # global strTxt_filename
        # print('max_row,max_column', worksheet.max_row, worksheet.max_column)
        # strTxt_filename += path + '\n'
        # strTxt_filename += str(worksheet.max_row) + ',' + str(worksheet.max_column)
        # strTxt_filename += '\r\n'
        # return
        
        # 遍历行何列 坐标从0开始
        for x in range(worksheet.max_row):
            strHtml += '<tr>'
            strHtml += '\n'
            for y in range(worksheet.max_column):
                row = x + 1
                col = y + 1
                cellValue = worksheet.cell(row, col).value
                # print('单元格内容:', cellValue)
                area = in_area(arr_area, row, col)
                if not area is None:# 是合并单元格
                    if is_first(area, row, col):
                        rowspan = area['r2']-area['r1']+1
                        colspan = area['c2']-area['c1']+1
                        # print('合并单元格:', area)
                        # print('rowspan,colspan:', rowspan, colspan)
                        # print('row,col,cellValue:', row, col, cellValue)                        
                        str_cellValue = cellValue if not cellValue is None and not str(cellValue).isspace() else '<input style="text-align:center" value="" />'                        
                        strHtml += '<td rowspan="{}" colspan="{}" style="white-space: pre-wrap;">{}</td>'.format(rowspan, colspan, str_cellValue)
                        strHtml += '\n'
                        # print(strHtml)
                    else:
                        # print('在合并单元格中,跳过')
                        a = 0
                else:# 非合并单元格
                    # print('单独的单元格')
                    str_cellValue = cellValue if not cellValue is None and not str(cellValue).isspace() else '<input style="text-align:center" value="" />'                        
                    strHtml += '<td colspan="1" style="white-space: pre-wrap;">{}</td>'.format(str_cellValue)
                    strHtml += '\n'
            strHtml += '</tr>'
            strHtml += '\n'
        
        return strHtml
        # # 保存文件
        # file=open(html_save_path, 'w', encoding = "utf-8") 
        # file.write(strHtml_tmp.replace('tmp_title',tmp_title).replace('tmp_content', strHtml)); 
        # file.close()     
    
    
    
    def show_files(path, all_files):
        file_list = os.listdir(path)
        for file in file_list:
            cur_path = os.path.join(path, file)
            basename = os.path.basename(path)
            if os.path.isdir(cur_path):# delete dir
                show_files(cur_path, all_files)
            else:# file            
                parent_dir = path.replace('C-1','')
                last_index = parent_dir.rfind('\\')
                parent_dir = parent_dir[last_index+1: ]                        
                print('cur_path', cur_path)
                # print('path', path)
                # print('file', file)
                # 得到新文件名
                filename_cn_center = re.findall(re.compile(r'[(](.*?)[)]', re.S), file)[0].replace('、','')
                filename_en = get_en_name(parent_dir)+'_'+get_en_name(filename_cn_center) 
                # print('filename_en', filename_en)
                
                global strTxt_filename
                global strTxt_methodname
                strTxt_filename += str(file)+','+filename_en+'\n'
                strTxt_methodname += '// '+str(file)+'\n public ActionResult '+filename_en+'(){return View();}\r\n'
                
                html_save_path = 'e:\\html\\{}.cshtml'.format(filename_en)
                tmp_title = filename_cn_center+'现场质量检验报告单'
                tmp_content = read_worksheet(cur_path)
                
                # 保存文件
                file=open(html_save_path, 'w', encoding = "utf-8") 
                html=str(strHtml_tmp)
                html=html.replace('tmp_title',tmp_title)
                html=html.replace('tmp_content',tmp_content)
                file.write(html);
                file.close()   
                
        return all_files
    
    
    
    
    # 读取模板
    f = open("e:\\tmp_html.cshtml", encoding = "utf-8")
    strHtml_tmp = f.read()
    f.close()
    
    contents = show_files("E:\\111", [])
    
    
    # 保存文件
    file=open("e:\\strTxt_filename.txt", 'w', encoding = "utf-8") 
    file.write(strTxt_filename); 
    file.close() 
    
    file=open("e:\\strTxt_methodname.txt", 'w', encoding = "utf-8") 
    file.write(strTxt_methodname); 
    file.close() 
    
    
    
    
    
    
    # html='tmp_title 间隔 tmp_content'
    # html=html.replace('tmp_title', '开始')
    # html=html.replace('tmp_content', '结束')
    # print(html)
    
    
    
    # 代码的核心逻辑---------------------
    
    # 遍历行
    # 遍历列
    # 单元格 在不在区域中
    # 是否是 区域的开头
    # 如果是开头,则用区域。如果不是开头,则跳过
    
    # 核心判断
    # 判断一个单元格(行和列) 是否在区域中
    # 判断一个单元格 是否是区域的开头
    
    
    
    # 13个列
    # 15个列
    
    
    # strHtml_tmp = ''
    # f = open("test1.cshtml",encoding = "utf-8")
    # strHtml_tmp = f.read()
    # f.close()
    
    
    # print('arr_area------------')
    # print(len(arr_area))
    # print(arr_area)
    
    # area = in_area(arr_area, 5, 1)
    # if not area is None:
        # is_first(area, 5, 1)        
    
    
    #def each_files():    
        #pathDir =  os.listdir('./files/')
        #for index, value in enumerate(pathDir):
            #filepath2 = './files/' + value
            #print(filepath2)
            #create_worksheet(filepath2)        
    
    #each_files()
    #workbook2.save('test2.xlsx')
    
    
    # https://pypi.org/project/xpinyin/
    # pip install -U xpinyin
    
    
    # create_worksheet('E://1-1.xlsx')
    
    
    # p = Pinyin()
    # res = p.get_initials("照明设施", '')
    # print(res)
    
    
    #string = 'abe(ac)ad)'
    #string = 'C-1现场质量检验报告单(照明设施).xls'
    #p1 = re.compile(r'[(](.*?)[)]', re.S) # 最小匹配
    
    
    
  • 相关阅读:
    IntelliJ IDEA 偏好设置
    Unix环境下的5中IO模型
    Hbase原理、基本概念、基本架构
    可参考的技术博客
    Hadoop生态系统介绍
    oracle 添加表分区和索引分区,修改索引分区默认表空间
    koa redis 链接
    Node-APN 开源推送服务
    NodeJs 笔记
    windows防火墙无法启动,服务不存在
  • 原文地址:https://www.cnblogs.com/guxingy/p/16259007.html
Copyright © 2020-2023  润新知