Python在实际工作中的运用-通用格式CSV文件自动转换XLSX

继续上篇《Python在实际工作中的运用-CSV无损转XLSX的几个方法》我们虽然对特定格式的CSV实现了快速转换XLSX的目标,但是在运行Py脚本前,还是需要编辑表格创建脚本和数据插入脚本,自动化程度很低,实用性不强,为减少人工提高效率,实现输入CSV文件路径即可自动适配完成转换。现将改进后的脚本发出来,供大家共同交流学习。

脚本说明:

1、本脚本适合字段之间用空格分隔或者用逗号分隔的CSV文本

2、只需将CSV文件路径(含文件名和扩展名)设置到file_path_name变量即可

3、SQlite是中间库,本脚本在执行转换前会自动删除重建。

4、转换的XLSX文件,字段名是自动命名的,请自行修改为自己的表头。

python 复制代码
import os
import sqlite3
import re
import time
import pandas as pd
from pathlib import Path

# 公共变量
# 待转换的CSV文件【必填】
file_path_name = f'{os.path.dirname(__file__)}/待转换的CSV文件.csv'

# 首行是否标题true是false否(默认为否)
isheader = False
# 设置字段之间的分割符号,默认是空格
delimiter = " "
# 获取入口文件目录
file_dirname = os.path.dirname(file_path_name)
# 获取入口文件名(不带扩展名)
file_name = Path(file_path_name).stem

# 删除重建数据库
dbfile_path_name = f'{file_dirname}/{file_name}.db'
if os.path.exists(dbfile_path_name):
    os.remove(dbfile_path_name)
    # 连接到 SQLite 数据库(如果数据库文件不存在,会自动创建一个新的数据库文件)
    conn = sqlite3.connect(dbfile_path_name)
else:
    conn = sqlite3.connect(dbfile_path_name)

cursor = conn.cursor()
sql = f"select name from sqlite_master where name='{file_name}';"
cursor.execute(sql)

# 创建数据表
def CreateTB(conn, header_name = None):
    cursor = conn.cursor()
    # fetchone逐行获取查询结果,如果没有结果返回则判断表未创建
    if not bool(cursor.fetchone()):
        with open(file_path_name,'r',encoding='utf-8') as file:
            # 获取字段个数
            line = file.readline()
            if delimiter == " ":
                line = re.sub(r'\s+',',',line)

            if re.findall('^,',line):
                line = re.sub('^,','',line)

            if re.findall(',$',line):
                line = re.sub(',$','',line)

            # 将整理好的文本分割成字段,并获得字段数
            line_split = line.split(',')
            sql = ""
            if isheader:
                for i in range(len(line_split)):
                    sql += f",{line_split[i]} TEXT NOT NULL"
                    #index_name = line_split[index_num]
                    header_name += f"{line_split[i]},"

                    if i == len(line_split) - 1:
                        header_name = re.sub(',$','',header_name)
            else:
                for i in range(len(line_split)):
                    sql += f",字段名{i} TEXT NOT NULL"
                    #index_name = f"字段名{index_num}"
                    header_name += f"字段名{i},"

                    if i == len(line_split) - 1:
                        header_name = re.sub(',$','',header_name)

            sql = f"CREATE TABLE IF NOT EXISTS {file_name}(id INTEGER PRIMARY KEY{sql});"

            cursor.execute(sql)
            #sql = f"CREATE UNIQUE INDEX IF NOT EXISTS tableindex ON {file_name} ({index_name});"
            #cursor.execute(sql)
            # 提交更改
            conn.commit()
            return header_name

# 调用创建数据表函数
header = CreateTB(conn,"")

with open(file_path_name,'r',encoding='utf-8') as file:
    lines = file.readlines()
    rownum = len(lines)

    i=0
    cursor.execute('BEGIN TRANSACTION')
    start_time = time.time()
    for line in lines:
        # 这里用到正则表达式对数据中存在的多个空格以及数据行前后逗号进行处理
        if delimiter == " ":
            line = re.sub(r'\s+',',',line)

        if re.findall('^,',line):
            line = re.sub('^,','',line)

        if re.findall(',$',line):
            line = re.sub(',$','',line)

        # 对整理完的文本,用逗号进行分割
        line_split = line.split(',')

        # 组装insert插入记录
        fieldsValue = ""
        for j in range(len(line_split)):
            fieldsValue += f"'{line_split[j]}',"
            if j == len(line_split) - 1:
                fieldsValue = re.sub(',$','',fieldsValue)

        try:
            sql = f"INSERT OR ignore INTO {file_name}({header}) VALUES ({fieldsValue});"
            cursor.execute(sql)
        except Exception as e:
            #conn.rollback()
            print(e)

        # 对操作进行计数
        i=i+1
        if i == rownum:
            conn.commit()

            # 在这里将导入的待转换CSV文件数据经过SQLite数据库转化为Excel表导出
            df = pd.read_sql_query(f'select * from {file_name}',conn)
            df.to_excel(f'{file_dirname}/{file_name}.xlsx',index=False)

# 输出执行结果
end_time = time.time()
print(f'共转换{i}行,操作完毕,执行时间:{end_time-start_time}秒')
相关推荐
奔跑吧邓邓子29 分钟前
【Python爬虫(67)】Python爬虫实战:探秘旅游网站数据宝藏
开发语言·爬虫·python·旅游网站
m0_7480385629 分钟前
NLP09-朴素贝叶斯问句分类(3/3)
人工智能·python·机器学习·自然语言处理·数据挖掘·nlp
HerrFu34 分钟前
可狱可囚的爬虫系列课程 15:防盗链反爬虫的处理
爬虫·python
HerrFu38 分钟前
可狱可囚的爬虫系列课程 14:10 秒钟编写一个 requests 爬虫
爬虫·python
数据知道39 分钟前
爬虫反爬:字体反爬案例分析与爬取实战
爬虫·python·数据采集·爬虫解析
猿毕设1 小时前
【FL0100】基于SSM微信小程序的走失人员的报备平台
java·spring boot·后端·python·微信小程序·小程序
猿毕设1 小时前
【FL0091】基于SSM和微信小程序的社区二手物品交易小程序
java·spring boot·后端·python·微信小程序·小程序
攻城狮_Dream1 小时前
基于 Python 的项目管理系统开发
android·数据库·python
崧小果2 小时前
Mobaxterm服务器常用命令(持续更新)
开发语言·python·深度学习
java1234_小锋2 小时前
一周学会Flask3 Python Web开发-Jinja2模板基本使用
python·flask·flask3