【问题标题】:Update SQL output data into Existing Excel in respective sheet using python使用 python 将 SQL 输出数据更新到相应工作表中的现有 Excel
【发布时间】:2018-01-22 07:07:27
【问题描述】:

我是 Python 编程新手,正在寻求一些帮助/指导来纠正我的 Python 代码。

这是我的查询。

  1. 我有一个 Excel 文件,其中包含(7 个标签)。
  2. 我有一个文件夹,其中包含 7 个不同的文本文件,每个文本文件都包含各自的选项卡 SQL 查询,每个文本文件名与 Excel 文件中的选项卡名称相同。

我编写了一个 Python 代码来逐个循环遍历所有文本文件并执行每个文本文件 SQL 查询以及将输出的任何数据,输出数据应转储到相应工作表/选项卡中的现有 excel 文件中.我正在使用 pandas 来执行此操作,但是,代码运行良好,但是在将数据更新到 excel 时,pandas 正在从文件中删除所有现有工作表,并且仅将当前输出数据更新到 excel 文件中。

示例:如果 Python 代码执行一个文本文件(文件名:数据),在执行此 SQL 查询后,我们得到了一些数据,这些数据应转储到 excel 文件(工作表名:数据)中。

<pre><code>
import pypyodbc
import pandas as pd
import os
import ctypes
from pandas import ExcelWriter
fpath = r"C:\MNaveed\DataScience\Python Practice New\SQL Queries"
xlfile = r"C:\MNaveed\DataScience\Python Practice New\SQL Queries\Open_Case_Data.xlsx"
cnxn = pypyodbc.connect('Driver={SQL Server};Server=MyServerName;Database=MyDatabaseName;Trusted_Connection=Yes')
cursor = cnxn.cursor()

for subdir, dirs, files in os.walk(fpath):
    for file in files:
        #print(os.path.join(subdir,file))
        filepath = os.path.join(subdir,file)
        #print("FilePath: ", filepath)

        if filepath.endswith(".txt"):
            if file != "ClosedAging_Cont.txt":
                txtdata = open(filepath, 'r')
                script = txtdata.read().strip()
                txtdata.close()
                cursor.execute(script)
                if file == "ClosedAging.txt":
                    txtdata = open(os.path.join(subdir,"ClosedAging_Cont.txt"), 'r')
                    script = txtdata.read().strip()
                    txtdata.close()
                    cursor.execute(script)

                col = [desc[0] for desc in cursor.description]
                data = cursor.fetchall()
                df = pd.DataFrame(list(data),columns=col)

                #save_xls(df,xlfile)

                writer = pd.ExcelWriter(xlfile)
                flnm = file.replace('.txt','').strip()
                df.to_excel(writer,sheet_name=flnm,index=False)
                writer.save()

                print(file, " : Successfully Updated.")
            else:
                print(file, " : Ignoring this File")
        else:
            print(file, " : Ignoring this File")

ctypes.windll.user32.MessageBoxW(0,"Open Case Reporting Data Successfully Updated","Open Case Reporting",1)
</pre></code>

【问题讨论】:

  • 据我所知,xlsxwriter 只是一名作家。它没有读取文件的能力,这意味着它无法查找您要附加数据的最后一行。您需要openpyxl 来查找空行。然后使用xlsxwriter 通过指定行来写入。或者您可以在openpyxl 中重新编写您的代码
  • 已格式化并修正错别字
  • 嗨 Muthu Kumaran,我不是在寻找附加数据。我想将数据转储到现有工作表中(现有数据应首先删除并转储更新的数据)。但是这里熊猫每次循环时都不会创建新的数据框..

标签: python excel


【解决方案1】:

通过循环遍历文本文件,您每次都会覆盖循环内的 Excel 文件。而是实例化 pd.ExcelWriter(xlfile) 并在循环外调用 writer.save() 。

以下示例改编自xlswriter documentation

您可以在此处找到有关多张工作表的更多信息:xlswriter documentaion - multiple sheets

import pandas as pd

# Create a Pandas Excel writer using XlsxWriter as the engine outside the loop.
writer = pd.ExcelWriter('pandas_simple.xlsx', engine='xlsxwriter')
# Sample loop, replace with directory browsing loop
for i in range(7):
    # Sample Pandas dataframe. Replace with SQL query and resulting data frame.
    df = pd.DataFrame({'DataFromSQLQuery': ['SQL query result {0}'.format(i)]})
    # Convert the dataframe to an XlsxWriter Excel object.
    df.to_excel(writer, sheet_name='Sheet{0}'.format(i))
# Close the Pandas Excel writer and output the Excel file.
writer.save()

以下代码解决了具体问题,但未经测试。

import pypyodbc
import pandas as pd
import os
import ctypes
from pandas import ExcelWriter

fpath = r"C:\MNaveed\DataScience\Python Practice New\SQL Queries"
xlfile = r"C:\MNaveed\DataScience\Python Practice New\SQL Queries\Open_Case_Data.xlsx"
cnxn = pypyodbc.connect('Driver={SQL Server};Server=MyServerName;Database=MyDatabaseName;Trusted_Connection=Yes')
cursor = cnxn.cursor()

# Create a Pandas Excel writer using XlsxWriter as the engine outside the loop
writer = pd.ExcelWriter('pandas_simple.xlsx', engine='xlsxwriter')

# File loop
for subdir, dirs, files in os.walk(fpath):
    for file in files:
        filepath = os.path.join(subdir,file)
        if filepath.endswith(".txt"):
            if file != "ClosedAging_Cont.txt":
                txtdata = open(filepath, 'r')
                script = txtdata.read().strip()
                txtdata.close()
                cursor.execute(script)
                if file == "ClosedAging.txt":
                    txtdata = open(os.path.join(subdir,"ClosedAging_Cont.txt"), 'r')
                    script = txtdata.read().strip()
                    txtdata.close()
                    cursor.execute(script)

                col = [desc[0] for desc in cursor.description]
                data = cursor.fetchall()

                # Data frame from original question
                df = pd.DataFrame(list(data),columns=col)

                # Convert the dataframe to an XlsxWriter Excel object
                flnm = file.replace('.txt','').strip()
                df.to_excel(writer, sheet_name=flnm, index=False)

                print(file, " : Successfully Updated.")
            else:
                print(file, " : Ignoring this File")
        else:
            print(file, " : Ignoring this File")

# Close the Pandas Excel writer and output the Excel file
writer.save()

ctypes.windll.user32.MessageBoxW(0,"Open Case Reporting Data Successfully Updated","Open Case Reporting",1)

【讨论】:

  • 嗨 silvanoe,非常感谢您的回复。上面的代码是删除现有的所有工作表并创建一个新工作表(Sheet0,Sheet1,....),并在每张工作表中转储相同的数据。我在这里担心的是,我的代码将一个接一个地获取每个文本文件,它将执行一个 SQL 查询,并且无论输出什么数据,这些数据都将转换为 pandas 数据框,并且我想将这些数据转储到特定的工作表中(无论是什么文本文件名称相同的名称将出现在excel表中)
  • 由于我无法复制您的数据库,因此数据框仅用作来自您的数据库查询的示例数据。您必须将这部分代码替换为您的数据库查询代码。循环计数到 7 也是如此,您必须将其替换为目录浏览循环。我用额外的 cmets 更新我的答案
  • 好的,谢谢Silvanoe,你能帮我把我的代码改成你的吗
      df = pd.DataFrame(list(data), columns=col) 
  • 好的,谢谢 Silvanoe,你能帮忙把我的代码改成你的
      df = pd.DataFrame(list(data), columns=col) 到你的格式 df = pd.DataFrame({'DataFromSQLQuery': ['SQL 查询结果 {0}'.format(i)]})
  • 我更改了您的代码并将其添加到答案中。请测试它并让我们知道它是否有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多