python查詢MySQL寫入Excel 四、自適應寬度

一、概述

 現有一個用戶表,需要將表數據寫入到excel中。

環境說明

mysql版本:5.7

端口:3306

數據庫:test

表名:users

 

表結構如下:

CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT '用戶名',
  `password` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '密碼',
  `phone` varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '手機號',
  `email` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '郵箱',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

 

插入3行數據

INSERT INTO `test`.`users` (`id`, `username`, `password`, `phone`, `email`, `create_time`) VALUES ('1', 'xiao', '123', '12345678910', '[email protected]', '2020-04-10 01:22:07');
INSERT INTO `test`.`users` (`id`, `username`, `password`, `phone`, `email`, `create_time`) VALUES ('2', 'zhang', '123', '12345678910', '[email protected]', '2020-04-10 01:22:07');
INSERT INTO `test`.`users` (`id`, `username`, `password`, `phone`, `email`, `create_time`) VALUES ('3', 'lisi', '123', '12345678910', '[email protected]', '2020-04-10 01:22:07');

 

二、基本寫法

安裝模塊

pip3 install xlwt pymysql

 

test_excel.py

#!/usr/bin/env python3
# coding: utf-8
import os
import xlwt
import pymysql
import datetime

class MysqlToExcel(object):
    def __init__(self):
        self.host = '10.212.21.92'
        self.user = 'root'
        self.passwd = 'abcd1234'
        self.db_name = 'test'
        self.port = 3306
        self.file_name = 'data.xls'

    def get_query_results(self):
        sql = "select * from test.users"

        conn = pymysql.connect(
            host=self.host,
            user=self.user,
            passwd=self.passwd,
            port=self.port,
            database=self.db_name,
            charset='utf8',
            cursorclass=pymysql.cursors.DictCursor
        )
        cur = conn.cursor()  # 創建遊標
        cur.execute(sql)  # 執行sql命令
        result = cur.fetchall()  # 獲取執行的返回結果
        # print(result)
        cur.close()
        conn.close()  # 關閉mysql 連接
        return result

    def generate_table(self):
        """
        生成excel表格
        :return:
        """
        # 刪除已存在的文件
        if os.path.exists(self.file_name):
            os.remove(self.file_name)

        result = self.get_query_results()
        # print(result)
        if not result:
            print("查詢結果爲空")
            return False

        # 創建excel對象
        f = xlwt.Workbook()
        sheet1 = f.add_sheet('Sheet1', cell_overwrite_ok=True)

        # 列字段
        column_names = ['id','username','password','phone','email']

        # 寫第一行,也就是列所在的行
        for i in range(0, len(column_names)):
            sheet1.write(0, i, column_names[i])

        # 寫入多行
        num = 0  # 計數器
        for i in result:
            sheet1.write(num + 1, 0, i['id'])
            sheet1.write(num + 1, 1, i['username'])
            sheet1.write(num + 1, 2, i['password'])
            sheet1.write(num + 1, 3, i['phone'])
            sheet1.write(num + 1, 4, i['email'])
            # 日期轉換爲字符串
            value = i['create_time'].strftime('%Y-%m-%d %H:%M:%S')
            sheet1.write(num + 1, 5, value)

            num += 1  # 自增1

        # 保存文件
        f.save(self.file_name)

        # 判斷文件是否存在
        if not os.path.exists(self.file_name):
            print("生成excel失敗")
            return False

        print("生成excel成功")
        return True

if __name__ == '__main__':
    MysqlToExcel().generate_table()
View Code

 

執行輸出:

生成excel成功

 

查看excel表

 

三、高級寫法

在基礎寫法中,需要指定表的字段,比如:['id','username','password','phone','email']

如果一個表有70個字段怎麼辦?一個寫筆記耗時間,能不能動態獲取表字段呢?答案是可以的。

由於我在創建遊標時,指定了pymysql.cursors.DictCursor,它返回的每一行數據,都是一個字典。

因此,通過dict.keys()就可以獲取表字段了。

另外,我還得將查詢結構中非string的轉換爲string類型。

 

test_excel.py

#!/usr/bin/env python3
# coding: utf-8
import os
import xlwt
import pymysql
import datetime

class MysqlToExcel(object):
    def __init__(self):
        self.host = '10.212.21.92'
        self.user = 'root'
        self.passwd = 'abcd1234'
        self.db_name = 'test'
        self.port = 3306
        self.file_name = 'data.xls'

    def get_query_results(self):
        sql = "select * from test.users"

        conn = pymysql.connect(
            host=self.host,
            user=self.user,
            passwd=self.passwd,
            port=self.port,
            database=self.db_name,
            charset='utf8',
            cursorclass=pymysql.cursors.DictCursor
        )
        cur = conn.cursor()  # 創建遊標
        cur.execute(sql)  # 執行sql命令
        result = cur.fetchall()  # 獲取執行的返回結果
        # print(result)
        cur.close()
        conn.close()  # 關閉mysql 連接
        return result

    def generate_table(self):
        """
        生成excel表格
        :return:
        """
        # 刪除已存在的文件
        if os.path.exists(self.file_name):
            os.remove(self.file_name)

        result = self.get_query_results()
        # print(result)
        if not result:
            print("查詢結果爲空")
            return False

        # 創建excel對象
        f = xlwt.Workbook()
        sheet1 = f.add_sheet('Sheet1', cell_overwrite_ok=True)

        # 第一行結果
        row0 = result[0]
        # 列字段
        column_names = list(row0)

        # 寫第一行,也就是列所在的行
        for i in range(0, len(row0)):
            sheet1.write(0, i, column_names[i])

        # 寫入多行
        # 行座標,從第2行開始,也是1
        for row_id in range(1, len(result) + 1):
            # 列座標
            for col_id in range(len(column_names)):
                # 寫入的值
                value = result[row_id - 1][column_names[col_id]]
                # 判斷爲日期時
                if isinstance(value, datetime.datetime):
                    value = result[row_id - 1][column_names[col_id]].strftime('%Y-%m-%d %H:%M:%S')

                # 寫入表格
                sheet1.write(row_id, col_id, value)

        # 保存文件
        f.save(self.file_name)

        # 判斷文件是否存在
        if not os.path.exists(self.file_name):
            print("生成excel失敗")
            return False

        print("生成excel成功")
        return True

if __name__ == '__main__':
    MysqlToExcel().generate_table()
View Code

執行腳本,結果同上!

 

四、自適應寬度

上面表格看着不美觀,寬度沒有自適應。

解決方法:

增加一個方法,獲取寬度

def get_maxlength(self,value, col):
    """
    獲取value最大佔位長度,用於確定導出的xlsx文件的列寬
    col : 表頭,也參與比較,解決有時候表頭過長的問題
    """
    # 長度列表
    len_list = []
    # 表頭長度
    width = 256 * (len(col) + 1)
    len_list.append(width)

    # 數據長度
    if len(value) >= 10:
        width = 256 * (len(value) + 1)
        len_list.append(width)

    return max(len_list)

 

完整代碼如下:

#!/usr/bin/env python3
# coding: utf-8
import os
import xlwt
import pymysql
import datetime

class MysqlToExcel(object):
    def __init__(self):
        self.host = '10.212.21.92'
        self.user = 'root'
        self.passwd = 'abcd1234'
        self.db_name = 'test'
        self.port = 3306
        self.file_name = 'data.xls'

    def get_query_results(self):
        sql = "select * from test.users"

        conn = pymysql.connect(
            host=self.host,
            user=self.user,
            passwd=self.passwd,
            port=self.port,
            database=self.db_name,
            charset='utf8',
            cursorclass=pymysql.cursors.DictCursor
        )
        cur = conn.cursor()  # 創建遊標
        cur.execute(sql)  # 執行sql命令
        result = cur.fetchall()  # 獲取執行的返回結果
        # print(result)
        cur.close()
        conn.close()  # 關閉mysql 連接
        return result

    def get_maxlength(self,value, col):
        """
        獲取value最大佔位長度,用於確定導出的xlsx文件的列寬
        col : 表頭,也參與比較,解決有時候表頭過長的問題
        """
        # 長度列表
        len_list = []
        # 表頭長度
        width = 256 * (len(col) + 1)
        len_list.append(width)

        # 數據長度
        if len(value) >= 10:
            width = 256 * (len(value) + 1)
            len_list.append(width)

        return max(len_list)


    def generate_table(self):
        """
        生成excel表格
        :return:
        """
        # 刪除已存在的文件
        if os.path.exists(self.file_name):
            os.remove(self.file_name)

        result = self.get_query_results()
        # print(result)
        if not result:
            print("查詢結果爲空")
            return False

        # 創建excel對象
        f = xlwt.Workbook()
        sheet1 = f.add_sheet('Sheet1', cell_overwrite_ok=True)

        # 第一行結果
        row0 = result[0]
        # 列字段
        column_names = list(row0)

        # 寫第一行,也就是列所在的行
        for i in range(0, len(row0)):
            sheet1.write(0, i, column_names[i])

        # 寫入多行
        # 行座標,從第2行開始,也是1
        for row_id in range(1, len(result) + 1):
            # 列座標
            for col_id in range(len(column_names)):
                # 寫入的值
                value = result[row_id - 1][column_names[col_id]]
                # 判斷爲日期時
                if isinstance(value, datetime.datetime):
                    value = result[row_id - 1][column_names[col_id]].strftime('%Y-%m-%d %H:%M:%S')

                # 獲取表格對象
                col = sheet1.col(col_id)
                if value:
                    if isinstance(value, int):
                        value = str(value)

                    # 獲取寬度
                    width = self.get_maxlength(value,column_names[col_id])

                    # 設置寬度
                    col.width = width
                # 寫入表格
                sheet1.write(row_id, col_id, value)

        # 保存文件
        f.save(self.file_name)

        # 判斷文件是否存在
        if not os.path.exists(self.file_name):
            print("生成excel失敗")
            return False

        print("生成excel成功")
        return True

if __name__ == '__main__':
    MysqlToExcel().generate_table()
View Code

執行腳本,查看excel

 

 這樣看着,就比較舒服了。

 

本文參考鏈接:

https://blog.csdn.net/baidu_41743195/article/details/103001210

https://blog.csdn.net/dl1456074580/article/details/87364999

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章