python 操作openpyxl导出Excel 设置单元格格式以及合并处理

  1. 贴上一个例子,里面设计很多用法,根据将相同日期的某些行合并处理。
  2. from openpyxl import Workbook                                                                                                                                 
    from openpyxl.styles import Font, Fill, Alignment, Border, Side, PatternFill                                                                                  
    from handlers.boss_accountant import PbOrderManageBase                                                                                                        
    from handlers.base.pub_func import ConfigFunc                                                                                                                 
    from dal.models import Shop                                                                                                                                   
    from dal.db_configs import DBSession                                                                                                                          
                                                                                                                                                                  
                                                                                                                                                                  
                                                                                                                                                                  
                                                                                                                                                                  
    def export_excel(filename, sheetname, content_body):                                                                                                          
        """                                                                                                                                                       
        Excel表格导出                                                                                                                                                 
        :param filename: 表格名称                                                                                                                                     
        :param sheetname: 工作表名称                                                                                                                                   
        :param content_body: 内容体                                                                                                                                  
        :return: None                                                                                                                                             
        """                                                                                                                                                       
        workbook = Workbook()                                                                                                                                     
                                                                                                                                                                  
        if not filename:                                                                                                                                          
            filename = "导出表格.xlsx"                                                                                                                                
                                                                                                                                                                  
        workbook_sheet = workbook.active                                                                                                                          
        if not sheetname:                                                                                                                                         
            sheetname = "工作表"                                                                                                                                     
        workbook_sheet.title = sheetname                                                                                                                          
                                                                                                                                                                  
        merge_dict, sheet_row_len, sheet_column_len = merge_content(content_body)                                                                                 
        print(merge_dict)                                                                                                                                         
        # 数据写入                                                                                                                                                    
        for row in content_body:                                                                                                                                  
            workbook_sheet.append(row)                                                                                                                            
                                                                                                                                                                  
        # 合并处理                                                                                                                                                    
        for key in merge_dict.keys():                                                                                                                             
            merge_data = merge_dict.get(key)                                                                                                                      
            if key == "title":                                                                                                                                    
                workbook_sheet.merge_cells(start_row=merge_data[0], start_column=merge_data[1],                                                                   
                                           end_row=merge_data[2], end_column=merge_data[3])                                                                       
                workbook_sheet.merge_cells(start_row=2, start_column=merge_data[1],                                                                               
                                           end_row=2, end_column=merge_data[3])                                                                                   
                workbook_sheet['A1'].font = Font(size=20, bold=True)                                                                                              
                workbook_sheet['A1'].alignment = Alignment(horizontal='center', vertical='center')                                                                
            else:                                                                                                                                                 
                # 使用sum求值                                                                                                                                         
                workbook_sheet.cell(row=merge_data[0] + 3, column=12).value = '=SUM({}:{})'.format(                                                               
                    format_value(str(merge_data[0] + 3), 10), format_value(str(merge_data[1] + 3), 10))                                                           
                workbook_sheet.cell(row=merge_data[0] + 3, column=14).value = '=SUM({}:{})'.format(                                                               
                    format_value(str(merge_data[0] + 3), 11), format_value(str(merge_data[1] + 3), 11))                                                           
                workbook_sheet.cell(row=merge_data[0] + 3, column=13).value = '=({}-{})'.format(                                                                  
                    format_value(str(merge_data[0] + 3), 12), format_value(str(merge_data[0] + 3), 14))                                                           
                                                                                                                                                                  
                for i in [2,12, 13, 14]:                                                                                                                          
                    workbook_sheet.merge_cells(start_row=merge_data[0]+3, start_column=i,                                                                         
                                               end_row=merge_data[1]+3, end_column=i)                                                                             
        # 合计求和                                                                                                                                                    
        for i in [12, 13, 14]:                                                                                                                                    
            workbook_sheet.cell(row=sheet_row_len, column=i).value = '=SUM({}:{})'.format(                                                                        
                format_value(3, i), format_value(sheet_row_len - 1, i))                                                                                           
                                                                                                                                                                  
        # 单元格底色                                                                                                                                                   
        last_row = workbook_sheet[sheet_row_len]                                                                                                                  
        for each_cell in last_row:                                                                                                                                
            each_cell.fill = PatternFill("solid", fgColor="00CDCD")                                                                                               
                                                                                                                                                                  
        # 边框设置                                                                                                                                                    
        for each_common_row in workbook_sheet.iter_rows("A1:{}".format(format_value(sheet_row_len, sheet_column_len))):                                           
            for each_cell in each_common_row:                                                                                                                     
                each_cell.border = Border(left=Side(style='thin', color='000000'),                                                                                
                                          right=Side(style='thin', color='000000'),                                                                               
                                          top=Side(style='thin', color='000000'),                                                                                 
                                          bottom=Side(style='thin', color='000000')                                                                               
                                          )                                                                                                                       
        workbook_sheet.column_dimensions['B'].width = 15                                                                                                          
        workbook_sheet.column_dimensions['C'].width = 20                                                                                                          
        workbook.save(filename)                                                                                                                                   
                                                                                                                                                                  
                                                                                                                                                                  
    def merge_content(content_body):                                                                                                                              
        """                                                                                                                                                       
        合并统计                                                                                                                                                      
        :param content_body: 数据体                                                                                                                                  
        :return: 合并字典                                                                                                                                             
        """                                                                                                                                                       
        sheet_column_len = len(content_body[3])                                                                                                                   
        sheet_row_len = len(content_body)                                                                                                                         
        merge_dict = {}                                                                                                                                           
                                                                                                                                                                  
        data_content = content_body[3:-1]                                                                                                                         
                                                                                                                                                                  
        merge_dict["title"] = (1, 1, 1, sheet_column_len)                                                                                                         
                                                                                                                                                                  
        current_data = data_content[0][1]                                                                                                                         
        current_row = 0                                                                                                                                           
        start_row = 1                                                                                                                                             
        end_row = 0                                                                                                                                               
                                                                                                                                                                  
        for data in data_content:                                                                                                                                 
            current_row += 1                                                                                                                                      
            x = data[1]                                                                                                                                           
            if data[1] == current_data:                                                                                                                           
                                                                                                                                                                  
                merge_dict[data[1]] = (start_row, current_row)                                                                                                    
            else:                                                                                                                                                 
                                                                                                                                                                  
                merge_dict[data[1]] = (current_row, current_row)                                                                                                  
                current_data = data[1]                                                                                                                            
                                                                                                                                                                  
                start_row = current_row                                                                                                                           
                                                                                                                                                                  
        return merge_dict, sheet_row_len, sheet_column_len                                                                                                        
                                                                                                                                                                  
                                                                                                                                                                  
    def format_value(row, column):                                                                                                                                
        """数字转ABC                                                                                                                                                 
        """                                                                                                                                                       
        change_dict = {                                                                                                                                           
            1: "A", 2: "B", 3: "C", 4: "D", 5: "E", 6: "F", 7: "G", 8: "H", 9: "I", 10: "J",                                                                      
            11: "K", 12: "L", 13: "M", 14: "N", 15: "O", 16: "P", 17: "Q", 18: "R", 19: "S", 20: "T",                                                             
            21: "U", 22: "V", 23: "W", 24: "X", 25: "Y", 26: "Z",                                                                                                 
        }                                                                                                                                                         
        column = change_dict.get(column)                                                                                                                          
        return str(column)+str(row)                                                                                                                               
                                                                                                                                                                  
                                                                                                                                                                  
    def export_func_new(args, session, shop_id):                                                                                                                  
        # check_time = 0                                                                                                                                          
        # debtor_id = 2884                                                                                                                                        
        # debtor_name: 肖小菜                                                                                                                                        
        # end_date:                                                                                                                                               
        # start_date: 2019 - 07                                                                                                                                   
        # statistic_date: 3                                                                                                                                       
        # data_type: 1                                                                                                                                            
        data_content = []                                                                                                                                         
        check_time = 0                                                                                                                                            
        from_date = "2019-07"                                                                                                                                     
        to_date = ""                                                                                                                                              
        debtor_name = "肖小菜"                                                                                                                                       
                                                                                                                                                                  
        if_success, query_data, *_ = PbOrderManageBase.common_get_credit_stream(args, session, shop_id, export=True,                                              
                                                                                need_sum=False, check_time=check_time                                             
        )                                                                                                                                                         
        if not if_success:                                                                                                                                        
            raise ValueError(query_data)                                                                                                                          
        fee_text = ConfigFunc.get_fee_text(session, shop_id)                                                                                                      
        get_weight_unit_text = ConfigFunc.get_weight_unit_text(session, shop_id)                                                                                  
                                                                                                                                                                  
        # 表店铺、客户名称                                                                                                                                                
        shop_name = session.query(Shop.shop_name).filter_by(id=shop_id).first()                                                                                   
        data_content.append([shop_name[0]])                                                                                                                       
        data_content.append(["客户:{}".format(debtor_name)])                                                                                                        
        # 表头                                                                                                                                                      
        fee_text_total = '{}小计'.format(fee_text)                                                                                                                  
        header_content = [                                                                                                                                        
            "序号", "日期", "货品名", "数量", "重量/{}".format(get_weight_unit_text), "单价", "货品小记", "押金小计", fee_text_total,                                                  
            "赊账金额","待还款", "赊账小记", "已还款", "待还款小计"                                                                                                                  
        ]                                                                                                                                                         
        file_name_begin = "客户还款"                                                                                                                                  
        data_content.append(header_content)                                                                                                                       
        # 还款数据                                                                                                                                                    
        index_num = 0                                                                                                                                             
        for single_data in query_data:                                                                                                                            
            index_num += 1                                                                                                                                        
            sales_time = single_data.get("sales_time", "")                                                                                                        
            if sales_time:                                                                                                                                        
                sales_time = sales_time.split(" ")[0]                                                                                                             
                                                                                                                                                                  
            _payback_money = single_data["unpayback_money"]                                                                                                       
            single_content = [index_num,                                                                                                                          
                              sales_time,                                                                                                                         
                              single_data["only_goods_name"],                                                                                                     
                              single_data["commission_mul"],                                                                                                      
                              single_data["sales_num"],                                                                                                           
                              "%s元/%s" % (single_data["fact_price"],                                                                                              
                                          single_data["goods_unit"]),                                                                                             
                              single_data["goods_total"],                                                                                                         
                              single_data["commission_mul"],                                                                                                      
                              single_data["deposit_total"],                                                                                                       
                              single_data["credit_cent"],                                                                                                         
                              _payback_money,                                                                                                                     
                              0,                                                                                                                                  
                              0,                                                                                                                                  
                              0]                                                                                                                                  
            data_content.append(single_content)                                                                                                                   
        # 表尾合计                                                                                                                                                    
        data_content.append(["合计"])                                                                                                                               
        config = ConfigFunc.get_config(session, shop_id)                                                                                                          
        if not config.enable_deposit:                                                                                                                             
            index_deposit_total = data_content[0].index("押金小计")                                                                                                   
            for data in data_content:                                                                                                                             
                data.pop(index_deposit_total)                                                                                                                     
                                                                                                                                                                  
        if not config.enable_commission:                                                                                                                          
            index_commission_total = data_content[0].index(fee_text_total)                                                                                        
            for data in data_content:                                                                                                                             
                data.pop(index_commission_total)                                                                                                                  
                                                                                                                                                                  
        file_name = "{}流水记录导出_{}~{}.xlsx".format(file_name_begin, from_date, to_date)                                                                             
        return file_name, data_content                                                                                                                            
                                                                                                                                                                  
                                                                                                                                                                  
    if __name__ == "__main__":                                                                                                                                    
        filename = "测试打印表格.xlsx"                                                                                                                                  
        sheetname = "工作表2"                                                                                                                                        
                                                                                                                                                                  
                                                                                                                                                                  
                                                                                                                                                                  
        session = DBSession()                                                                                                                                     
        args = {                                                                                                                                                  
            "check_time": 0,                                                                                                                                      
            "debtor_id": 2884,                                                                                                                                    
            "debtor_name": "肖小菜",                                                                                                                                 
            "start_date": "2019-07",                                                                                                                              
            "statistic_date": 3,                                                                                                                                  
            "data_type": 1                                                                                                                                        
        }                                                                                                                                                         
        filename, content_body = export_func_new(args, session, 104)                                                                                              
                                                                                                                                                                  
                                                                                                                                                                  
        # filename = "测试打印表格.xlsx"                                                                                                                                
        # sheetname = "工作表2"                                                                                                                                      
        # content_body = []                                                                                                                                       
        # content_body.append(["打印表格表头"])                                                                                                                         
        # content_body.append(["客户:肖某某"])                                                                                                                         
        # content_body.append(["日期", "货品销售", "自营销售", "代卖销售", "联营销售", "总价"])                                                                                       
        # content_body.append(["1", "2", "3.1", "4.1", "5.1", "5.1"])                                                                                             
        # content_body.append(["1", "2", "3.1", "4.1", "5.1", "5.1"])                                                                                             
        # content_body.append(["1", "2", "3.1", "4.1", "5.1", "5.1"])                                                                                             

     

      

转载于:https://www.cnblogs.com/longbigbeard/p/11204115.html

<think>好的,用户现在问的是如何在Python导出Excel时调整行列和合并单元格。我需要结合之前的对话历史来给出合适的回答。用户之前遇到了关于Pandas导出Excel时缺少扩展名或引擎的问题,现在他们可能在使用Pandas导出Excel时想要进行更复杂的格调整,比如调整行高列宽,或者合并单元格。 首先,我需要确认用户的需求。他们可能已经知道如何用Pandas导出Excel,但现在需要进一步美化输出的表格,使其看起来更专业。调整行列大小和合并单元格是常见的需求,特别是在生成报告时。 接下来,我需要回忆Pandas本身是否支持这些操作。Pandas的to_excel方法确实可以导出数据到Excel,但默认情况下格比较基础。要实现行列调整和合并单元格,可能需要用到额外的库,比如openpyxl或xlsxwriter,这些库提供了更多格设置的功能。 然后,我应该考虑用户可能不熟悉这些库的使用,所以需要给出具体的步骤和示例代码。例如,使用openpyxl来调整列宽和行高,或者合并单元格。同时,要指出Pandas默认使用的引擎可能不同,需要指定engine参数为openpyxl。 另外,用户可能还需要知道如何应用样,比如设置字体、对齐方或者边框。这部分内容虽然用户没有直接提到,但通常和行列调整一起使用,可以适当补充,但不要偏离主题太远。 还需要注意之前用户遇到的错误,比如引擎问题,所以在示例中要确保正确指定引擎,避免用户再次遇到类似的错误。例如,在导出时使用engine='openpyxl',并提醒安装必要的库。 另外,用户可能在处理数据时希望合并某些单元格,比如标题行或者相同内容的单元格。这时候需要展示如何通过openpyxl的merge_cells方法来实现,可能还需要在数据导出后对工作表进行后续处理。 还要考虑不同情况下的处理,比如如何根据内容自动调整列宽,或者手动设置固定的列宽。提供两种方法会让回答更全面。 最后,总结一下关键点,确保用户能够按照步骤操作,并指出需要安装的库以及常见问题的解决方法,比如引擎指定和路径问题。</think>--- ### **1. 基础方法:使用 Pandas 直接导出** Pandas 的 `to_excel` 方法可快速导出 DataFrame 到 Excel,但 **默认不支持复杂格调整**。 **示例代码**: ```python import pandas as pd data = { "姓名": ["张三", "李四", "王五"], "成绩": [90, 85, 88], "班级": ["A班", "A班", "B班"] } df = pd.DataFrame(data) # 导出Excel df.to_excel("output.xlsx", index=False, engine="openpyxl") ``` --- ### **2. 调整行高与列宽** 需借助 `openpyxl` 或 `xlsxwriter` 进行精细化控制。以下以 `openpyxl` 为例: #### **方法一:根据内容自动调整列宽** ```python from openpyxl import load_workbook # 导出 DataFrame df.to_excel("output.xlsx", index=False, engine="openpyxl") # 加载工作簿并调整列宽 wb = load_workbook("output.xlsx") ws = wb.active # 自动调整所有列宽(按内容长度) for column in ws.columns: max_length = 0 column_letter = column[0].column_letter for cell in column: try: if len(str(cell.value)) > max_length: max_length = len(str(cell.value)) except: pass adjusted_width = (max_length + 2) * 1.2 # 留出边距 ws.column_dimensions[column_letter].width = adjusted_width wb.save("output_adjusted.xlsx") ``` #### **方法二:手动设置行高和列宽** ```python # 导出后手动设置 wb = load_workbook("output.xlsx") ws = wb.active # 设置第一行行高为 25 ws.row_dimensions[1].height = 25 # 设置 A 列宽度为 15 ws.column_dimensions['A'].width = 15 wb.save("output_manual.xlsx") ``` --- ### **3. 合并单元格** 通过 `openpyxl` 的 `merge_cells` 方法实现合并: #### **示例 1:合并标题行** ```python wb = load_workbook("output.xlsx") ws = wb.active # 合并 A1 到 C1 单元格作为标题 ws.merge_cells('A1:C1') ws['A1'] = "学生成绩表" ws['A1'].alignment = Alignment(horizontal='center', vertical='center') wb.save("output_merged_title.xlsx") ``` #### **示例 2:合并相同内容的单元格** ```python # 合并 "班级" 列中相同值的单元格 current_class = None start_row = 2 # 数据从第2行开始 for row in range(2, ws.max_row + 1): class_value = ws[f'C{row}'].value if class_value == current_class: end_row = row else: if current_class is not None and start_row < end_row: ws.merge_cells(f'C{start_row}:C{end_row}') current_class = class_value start_row = row wb.save("output_merged_class.xlsx") ``` --- ### **4. 完整流程示例** 结合行列调整与合并单元格的完整代码: ```python import pandas as pd from openpyxl import load_workbook from openpyxl.styles import Alignment # 创建 DataFrame data = { "姓名": ["张三", "李四", "王五", "赵六"], "成绩": [90, 85, 88, 92], "班级": ["A班", "A班", "B班", "B班"] } df = pd.DataFrame(data) # 导出基础文件 df.to_excel("students.xlsx", index=False, engine="openpyxl") # 加载工作簿并编辑格 wb = load_workbook("students.xlsx") ws = wb.active # 合并标题行 ws.merge_cells('A1:C1') ws['A1'] = "学生成绩表" ws['A1'].alignment = Alignment(horizontal='center', vertical='center') # 自动调整列宽 for col in ws.columns: max_length = max(len(str(cell.value)) for cell in col) adjusted_width = (max_length + 2) * 1.2 column_letter = col[0].column_letter ws.column_dimensions[column_letter].width = adjusted_width # 合并相同班级的单元格 current_class = None start_row = 2 for row in range(2, ws.max_row + 1): class_value = ws[f'C{row}'].value if class_value == current_class: end_row = row else: if current_class is not None and start_row < end_row: ws.merge_cells(f'C{start_row}:C{end_row}') current_class = class_value start_row = row wb.save("students_final.xlsx") ``` --- ### **关键点总结** 1. **依赖库安装**: ```bash pip install pandas openpyxl ``` 2. **引擎选择**: 导出 Excel 时需指定 `engine="openpyxl"`(默认引擎可能不支持格调整)。 3. **合并逻辑**: - 合并前需定位目标单元格的坐标(如 `'A1:C1'`)。 - 合并后需设置对齐方(如居中)以保证美观。 4. **性能优化**: 对大型数据集频繁操作单元格时,建议先处理数据再导出,避免多次读写文件。 --- ### **扩展应用** - **添加边框与颜色**:使用 `openpyxl.styles.Border` 和 `PatternFill` 设置单元格。 - **条件格**:通过 `ConditionalFormatting` 实现数据高亮。 - **公插入**:直接在单元格中写入 Excel(如 `=SUM(A2:A10)`)。 如果需要更高级的格控制,建议直接使用 `openpyxl` 或 `xlsxwriter` 的完整 API 进行开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值