简体   繁体   English

通过要求用户从目录中选择 Excel 工作簿和工作表将 Excel 文件转换为 Pandas 数据框

[英]Convert an Excel File to a Pandas Data Frame by Asking User to Choose Excel Workbook and Worksheet From Directory

I'm looking to create a Pandas data frame by asking the user to choose a file from their directory.我希望通过要求用户从他们的目录中选择一个文件来创建一个 Pandas 数据框。 In addition to choosing the file, though, I'm looking to also specify a specific sheet in the file.但是,除了选择文件之外,我还希望在文件中指定一个特定的工作表。 If only one sheet exists, then automatically choose the first one.如果只存在一张纸,则自动选择第一张。

I have tried the code below:我试过下面的代码:

import pandas as pd
import tkinter as tk
from tkinter import filedialog

root = tk.Tk()
root.withdraw()

file_path = filedialog.askopenfilename()

df = pd.read_excel(file_path, sheet_name = 1)
df

This works, but it doesn't provide the user the ability to choose which sheet of the excel file they'd like to use.这可行,但它不让用户能够选择他们想要使用的 Excel 文件的哪张表。 Perhaps a new window should pop up (if there's more than one sheet) and ask the user to select which sheet names are available.也许应该弹出一个新窗口(如果有多个工作表)并要求用户选择可用的工作表名称。 If only one sheet is available, then it should automatically choose the first sheet.如果只有一张纸可用,那么它应该自动选择第一张纸。

# Jupyter notebook

import pandas as pd
import ipywidgets as widgets
from IPython.display import clear_output
from ipyfilechooser import FileChooser
from ipywidgets import interact
from pathlib import Path

# get home dir of user
home = str(Path.home()) 

# initialize a dict for the excel file; this removes the need to set global values
dict_file = {}

# change to simply `home` if you want users to navigate through diff dirs
fc = FileChooser(f'{home}/excel') 

# same here
fc.sandbox_path = f'{home}/excel'

# limit file extensions to '.xls, .xlsb, .xlsm, .xlsx'
fc.filter_pattern = ['*.xls*']
fc.title = '<b>Select Excel file</b>'
display(fc)

# create empty dropdown for sheet names
dropdown = widgets.Dropdown(options=[''], value='', description='Sheets:', disabled=False)

# create output frame for the df
out = widgets.Output(layout=widgets.Layout(display='flex', flex_flow='column', align_items='flex-start', width='100%'))

# callback func for FileChooser
def get_sheets(chooser): 

    # (re)populate dict
    dict_file.clear() 
    dict_file['file'] = pd.ExcelFile(fc.value)
    sheet_names = dict_file['file'].sheet_names
    
    # only 1 sheet, we'll print this one immediate (further below)
    if len(sheet_names) == 1:
        
        # set value of the dropdown to this sheet
        dropdown.options = sheet_names
        dropdown.value = sheet_names[0]
        
        # disable the dropdown; so it's just showing the selection to the user
        dropdown.disabled = True
    else:
        
        # append empty string and set this as default; this way the user must always make a deliberate choice
        sheet_names.append('')
        dropdown.options = sheet_names
        dropdown.value = sheet_names[-1]
        
        # allow selection by user
        dropdown.disabled = False
    return

# bind FileChooser to callback
fc.register_callback(get_sheets)

# prompt on selection sheet
def show_df(sheet):
    if sheet == '':
        if out != None:
            # clear previous df, when user selects a new wb
            out.clear_output()
    else:
        # clear previous output 'out' frame before displaying new df, else they'll get stacked
        out.clear_output()
        with out:
            df = dict_file['file'].parse(sheet_name=sheet)
            if len(df) == 0:
                # if sheet is empty, let the user know
                display('empty sheet')
            else:
                display(df)
    return

# func show_df is called with input of widget as param on selection sheet
interact(show_df, sheet=dropdown)

# display 'out' (with df)
display(out)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM