python处理excel文件(这里只说明了excel文件的写入、保存和文件流处理excel文件)

python处理excel文件,一般主要分为xls,xlsx,csv三种。可以写入excel文件并保存至本地,也可以使用文件流,使用浏览器下载文件而实现不用保存至本地,缩减占用的空间。
xls文件最多可保存65536行,xlsx最多可保存1048756行,csv不限。在excel文件中Ctrl+↓,可直接到文件最低处,可查看文件最大行数。

1.python写入xls文件并保存至本地,在浏览器中可以下载。使用第三方库xlsxwriter

import xlsxwriter



def import_sell_number(self, context, sell_order_ids=None):

        """
        导出销售额模板
        :return:
        """

        # 判断导出数量
        _domain = [('flow_state', 'in', ['start', 'paypal_valited','sell_order_done','packing','packed', 'sended','out_stock','return','received','canceled','completed','copy_invalid'])]
        if sell_order_ids:
            orders = self.env['sell.order'].search([('id', 'in', sell_order_ids)], order='date')

        elif len(context['active_ids']) == 80:
            domain = self._context.get('active_domain', [])
            domain.extend(_domain)
            orders = self.env['sell.order'].search(domain, order='date')
        else:
            _domain.append(('id', 'in', context['active_ids']))
            orders = self.env['sell.order'].search(_domain, order='date')
        records_list = []
        for order in orders:
            is_begin = True
            for index, line in enumerate(order.sell_order_line_split_id): # 可以同时获取索引,值
                temp = []
                if is_begin:
                    temp.append(order.store_site_id.name) # 销售站点
                else:
                    temp.append(None)
                temp.append(order.store_id.name) # 所属店铺
                temp.append(order.site_order_id) # 平台原有订单ID
                temp.append(order.transaction_id) # 交易ID
                temp.append(order.country_id.cn_name) #  国家
                temp.append(line.goods_id.name) # 物品sku
                temp.append(line.quantity) # 数量
                if is_begin:
                    temp.append(order.amount)  # 订单金额(优惠后金额)
                else:
                    temp.append(None)
                temp.append(order.shipping_id.name) # 快递方式
                if is_begin:
                    temp.append(order.tracking_number)  # 快递单号
                    temp.append(order.send_time)  # 发货时间

                else:
                    temp.append(None)
                    temp.append(None)

                # 如果订单状态为已作废或复制单作废,则填充满
                if order.flow_state in FLOW_STATES.keys():
                    temp.append(FLOW_STATES[order.flow_state])  # 订单状态
                else:
                    temp.append(order.flow_state)  # 订单状态

                if is_begin:
                    temp.append(order.name)  # 快递单号
                else:
                    temp.append(None)
                records_list.append(temp)
                is_begin = False


            for item in order.sell_order_item_ids:
                if not item.is_compared:
                    temp = []
                    if is_begin:
                        temp.append(order.store_site_id.name)  # 销售站点
                    else:
                        temp.append(None)
                    temp.append(order.store_id.name)  # 所属店铺
                    temp.append(order.site_order_id)  # 平台原有订单ID
                    temp.append(order.transaction_id)  # 交易ID
                    temp.append(order.country_id.cn_name)  # 国家
                    temp.append(str(item.outside_sku))# + "**"
                    temp.append(item.quantity)
                    if is_begin:
                        temp.append(order.amount)  # 订单金额(优惠后金额)
                    else:
                        temp.append(None)
                    temp.append(order.shipping_id.name)  # 快递方式
                    if is_begin:
                        temp.append(order.tracking_number)  # 快递单号
                        temp.append(order.send_time)  # 发货时间

                    else:
                        temp.append(None)
                        temp.append(None)
                    # 如果订单状态为已作废或复制单作废,则填充满
                    if order.flow_state in FLOW_STATES.keys():
                        temp.append(FLOW_STATES[order.flow_state])  # 订单状态
                    else:
                        temp.append(order.flow_state)  # 订单状态

                    if is_begin:
                        temp.append(order.name)  # 快递单号
                    else:
                        temp.append(None)
                    records_list.append(temp)
                    is_begin = False

        col_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','I','J','K','L','M']
        file_path = os.getcwd() + u'/myaddons/retail/static/'
        file_name = file_path + u'import_sell_number.xlsx'

        if os.path.exists(file_name) and os.path.isfile(file_name):  # 检测文件是已经存在
            os.remove(file_name)

        workbook = xlsxwriter.Workbook(file_name)
        worksheet = workbook.add_worksheet()
        # 设置列宽20cm
        worksheet.set_column(0, 8, 20)
        worksheet.write('A1', u'销售渠道')
        worksheet.write('B1', u'销售账号')
        worksheet.write('C1', u'平台原有订单ID')
        worksheet.write('D1', u'交易ID')
        worksheet.write('E1', u'国家中文')
        worksheet.write('F1', u'物品SKU')
        worksheet.write('G1', u'数量')
        worksheet.write('H1', u'订单金额')
        worksheet.write('I1', u'快递方式')
        worksheet.write('J1', u'快递单号')
        worksheet.write('K1', u'发货时间')
        worksheet.write('L1', u'订单状态')
        worksheet.write('M1', u'单据编号')

        for m, j in enumerate(records_list):
            for n, k in enumerate(j):
                worksheet.write(str(col_list[n]) + str(m + 2), k)
        workbook.close()
        return {
            "type": "ir.actions.act_url",
            "url": "/retail/static/import_sell_number.xlsx",
            "target": "_blank",
        }

2.python写入xls文件,使用文件流处理文件,可在不保存至本地的情况下通过浏览器下载。使用第三方库xllwt 和文件流StringIO。前提是先有一个download.excel模型用户保存在浏览器中下载的文件至数据库中,这个模型可以是瞬态模型,定期清理。

import xlwt 
import StringIO

# 导出销售额模板
    def import_sell_number(self, active_ids, context):

        datas = [u'销售渠道', u'销售账号',u'平台原有订单ID',u'交易ID', u'国家中文', u'物品SKU', u'数量', u'订单金额', u'快递方式', u'快递单号'
            , u'发货时间', u'订单状态', u'单据编号']

        wb = xlwt.Workbook()

        filename=(u'导出销售额模板.xlsx')
        sh = wb.add_sheet('sheet1')
        index = 0
        for data in datas:
            sh.write(0,index,data)
            index += 1

        sell_order_list=[]
        # 判断导出数量
        _domain = [('flow_state', 'in', ['start', 'paypal_valited','sell_order_done','packing','packed', 'sended','out_stock','return','received','canceled','completed','copy_invalid'])]
        if len(context['active_ids']) == 80:
            domain = self._context.get('active_domain', [])
            domain.extend(_domain)
            sell_order_list = self.env['sell.order'].search(domain, order='date')
        else:
            _domain.append(('id', 'in', context['active_ids']))
            sell_order_list = self.env['sell.order'].search(_domain, order='date')

        if len(sell_order_list)>20000:
            raise UserError(u"一次最多下载20000条记录!")

        row_index = 1
        for order in sell_order_list:
            is_begin = True
            for index, line in enumerate(order.sell_order_line_split_id):  # 可以同时获取索引,值
                if is_begin:
                    site_name = order.store_site_id.name # 销售站点
                else:
                    site_name = None
                store_name = order.store_id.name #  所属店铺
                orgin_id = order.site_order_id # 平台原有订单ID
                transaction_id = order.transaction_id # 交易ID
                country_name = order.country_id.cn_name #  国家
                goods_sku = line.goods_id.name # 物品sku
                goods_number = line.quantity # 数量
                if is_begin:
                    amount = order.amount # 订单金额(优惠后金额)
                else:
                    amount = None
                shipping_name = order.shipping_id.name# 快递方式
                if is_begin:
                    tracking_number = order.tracking_number # 快递单号
                    send_time = order.send_time # 发货时间

                else:
                    tracking_number = None
                    send_time = None

                if order.flow_state in FLOW_STATES.keys():
                    flow_state = FLOW_STATES[order.flow_state]
                else:
                    flow_state = order.flow_state

                if is_begin:
                    order_name = order.name # 快递单号
                else:
                     order_name = None
                is_begin = False

                col_index = 0
                sh.write(row_index, col_index, site_name)
                col_index += 1
                sh.write(row_index, col_index, store_name)
                col_index += 1
                sh.write(row_index, col_index, orgin_id)
                col_index += 1
                sh.write(row_index, col_index, transaction_id)
                col_index += 1
                sh.write(row_index, col_index, country_name)
                col_index += 1
                sh.write(row_index, col_index, goods_sku)
                col_index += 1
                sh.write(row_index, col_index, goods_number)
                col_index += 1
                sh.write(row_index, col_index, amount)
                col_index += 1
                sh.write(row_index, col_index, shipping_name)  # lhz-20180904
                col_index += 1
                sh.write(row_index, col_index, tracking_number)
                col_index += 1
                sh.write(row_index, col_index, send_time)
                col_index += 1
                sh.write(row_index, col_index, flow_state)
                col_index += 1
                sh.write(row_index, col_index, order_name)
                row_index += 1

            for item in order.sell_order_item_ids:

                if not item.is_compared:
                    if is_begin:
                        site_name = order.store_site_id.name  # 销售站点
                    else:
                        site_name = None
                    store_name = order.store_id.name  # 所属店铺
                    orgin_id = order.site_order_id  # 平台原有订单ID
                    transaction_id = order.transaction_id  # 交易ID
                    country_name = order.country_id.cn_name  # 国家
                    goods_sku = str(item.outside_sku)+"**" # 物品sku
                    goods_number = item.quantity  # 数量
                    if is_begin:
                        amount = order.amount  # 订单金额(优惠后金额)
                    else:
                        amount = None
                    shipping_name = order.shipping_id.name  # 快递方式
                    if is_begin:
                        tracking_number = order.tracking_number  # 快递单号
                        send_time = order.send_time  # 发货时间
                    else:
                        tracking_number = None
                        send_time = None

                    if order.flow_state in FLOW_STATES.keys():
                        flow_state = FLOW_STATES[order.flow_state]
                    else:
                        flow_state = order.flow_state
                    if is_begin:
                        order_name = order.name  # 快递单号
                    else:
                        order_name = None

                    is_begin = False

                    col_index = 0
                    sh.write(row_index, col_index, site_name)
                    col_index += 1
                    sh.write(row_index, col_index, store_name)
                    col_index += 1
                    sh.write(row_index, col_index, orgin_id)
                    col_index += 1
                    sh.write(row_index, col_index, transaction_id)
                    col_index += 1
                    sh.write(row_index, col_index, country_name)
                    col_index += 1
                    sh.write(row_index, col_index, goods_sku)
                    col_index += 1
                    sh.write(row_index, col_index, goods_number)
                    col_index += 1
                    sh.write(row_index, col_index, amount)
                    col_index += 1
                    sh.write(row_index, col_index, shipping_name)  # lhz-20180904
                    col_index += 1
                    sh.write(row_index, col_index, tracking_number)
                    col_index += 1
                    sh.write(row_index, col_index, send_time)
                    col_index += 1
                    sh.write(row_index, col_index, flow_state)
                    col_index += 1
                    sh.write(row_index, col_index, order_name)
                    row_index += 1
            if row_index >= 65535:
                raise  UserError(U'导出数据太多,请减少导出条数!')

        fp = StringIO.StringIO()
        wb.save(fp)

        export_id = self.env['download.excel'].create({
            'excel_file': base64.encodestring(fp.getvalue()),
            'file_name': filename
        })



        fp.close()

        context['action'] = {
            'view_mode': 'form',
            'res_id': export_id.id,
            'res_model': 'download.excel',
            'view_type': 'form',
            'type': 'ir.actions.act_window',
            'context': self._context,
            'target': 'new',
        }



3.python写入xlsx文件使用文件流处理文件,可在不保存至本地的情况下通过浏览器下载。使用第三方库openpyxl和文件流StringIO

 # 导出销售额模板
    def import_sell_number(self, active_ids, context):
        '''
        xls 最大行数为65536
        xlsx最大行数为1048576

        :param active_ids:
        :param context:
        :return:
        '''

        datas = [u'销售渠道', u'销售账号',u'平台原有订单ID',u'交易ID', u'国家中文', u'物品SKU', u'数量', u'订单金额', u'快递方式', u'快递单号'
            , u'发货时间', u'订单状态', u'单据编号']

        workbook = Workbook()
        booksheet = workbook.active  # 获取当前活跃的sheet,默认是sheet1

        filename=(u'导出销售额模板.xlsx')

        # 存第一行单元格cell(1,1)
        index = 1
        for data in datas:
            booksheet.cell(1,index).value=data
            index += 1

        sell_order_list=[]
        # 判断导出数量
        _domain = [('flow_state', 'in', ['start', 'paypal_valited','sell_order_done','packing','packed', 'sended','out_stock','return','received','canceled','completed','copy_invalid'])]
        if len(context['active_ids']) == 80:
            domain = self._context.get('active_domain', [])
            domain.extend(_domain)
            sell_order_list = self.env['sell.order'].search(domain, order='date')
        else:
            _domain.append(('id', 'in', context['active_ids']))
            sell_order_list = self.env['sell.order'].search(_domain, order='date')

        if len(sell_order_list)>20000:
            raise UserError(u"一次最多下载20000条记录!")

        row_index = 1
        for order in sell_order_list:
            is_begin = True
            for index, line in enumerate(order.sell_order_line_split_id):  # 可以同时获取索引,值
                if is_begin:
                    site_name = order.store_site_id.name # 销售站点
                else:
                    site_name = None
                store_name = order.store_id.name #  所属店铺
                orgin_id = order.site_order_id # 平台原有订单ID
                transaction_id = order.transaction_id # 交易ID
                country_name = order.country_id.cn_name #  国家
                goods_sku = line.goods_id.name # 物品sku
                goods_number = line.quantity # 数量
                if is_begin:
                    amount = order.amount # 订单金额(优惠后金额)
                else:
                    amount = None
                shipping_name = order.shipping_id.name# 快递方式
                if is_begin:
                    tracking_number = order.tracking_number # 快递单号
                    send_time = order.send_time # 发货时间

                else:
                    tracking_number = None
                    send_time = None

                if order.flow_state in FLOW_STATES.keys():
                    flow_state = FLOW_STATES[order.flow_state]
                else:
                    flow_state = order.flow_state

                if is_begin:
                    order_name = order.name # 快递单号
                else:
                     order_name = None
                is_begin = False
                booksheet.append([site_name,
                                  store_name,
                                  orgin_id,
                                  transaction_id,
                                  country_name,
                                  goods_sku,
                                  goods_number,
                                  amount,
                                  shipping_name,
                                  tracking_number,
                                  send_time,
                                  flow_state,
                                  order_name
                                  ])
                row_index += 1

            for item in order.sell_order_item_ids:

                if not item.is_compared:
                    if is_begin:
                        site_name = order.store_site_id.name  # 销售站点
                    else:
                        site_name = None
                    store_name = order.store_id.name  # 所属店铺
                    orgin_id = order.site_order_id  # 平台原有订单ID
                    transaction_id = order.transaction_id  # 交易ID
                    country_name = order.country_id.cn_name  # 国家
                    goods_sku = str(item.outside_sku)+"**" # 物品sku
                    goods_number = item.quantity  # 数量
                    if is_begin:
                        amount = order.amount  # 订单金额(优惠后金额)
                    else:
                        amount = None
                    shipping_name = order.shipping_id.name  # 快递方式
                    if is_begin:
                        tracking_number = order.tracking_number  # 快递单号
                        send_time = order.send_time  # 发货时间
                    else:
                        tracking_number = None
                        send_time = None

                    if order.flow_state in FLOW_STATES.keys():
                        flow_state = FLOW_STATES[order.flow_state]
                    else:
                        flow_state = order.flow_state
                    if is_begin:
                        order_name = order.name  # 快递单号
                    else:
                        order_name = None

                    is_begin = False
                    booksheet.append([site_name,
                                      store_name,
                                      orgin_id,
                                      transaction_id,
                                      country_name,
                                      goods_sku,
                                      goods_number,
                                      amount,
                                      shipping_name,
                                      tracking_number,
                                      send_time,
                                      flow_state,
                                      order_name
                                      ])
                    row_index += 1
            if row_index >= 1048575:
                raise  UserError(U'导出数据太多,请减少导出条数!')
        workbook.save(filename)
        fp = StringIO.StringIO()
        workbook.save(fp)

        export_id = self.env['download.excel'].create({
            'excel_file': base64.encodestring(fp.getvalue()),
            'file_name': filename
        })


        fp.close()

        context['action'] = {
            'view_mode': 'form',
            'res_id': export_id.id,
            'res_model': 'download.excel',
            'view_type': 'form',
            'type': 'ir.actions.act_window',
            'context': self._context,
            'target': 'new',
        }


你可能感兴趣的:(python处理excel文件(这里只说明了excel文件的写入、保存和文件流处理excel文件))