Python tương tác với powershell
Gần đây, tôi đang làm việc trên một số trường hợp sử dụng để sửa đổi các báo cáo mỏng Power BI theo chương trình bằng pbi-tools và Python. Một trường hợp sử dụng ví dụ gần đây là đặt tất cả độ rộng cột trong bảng và ma trận thành cùng một kích thước. Để dịch ngược các báo cáo sang mã nguồn của họ, cho đến bây giờ, tôi chủ yếu sử dụng các công cụ pbi từ PowerShell, chẳng hạn, bằng cách tự động hóa nó bất cứ khi nào tôi lưu một. pbix bằng quy trình Power Automate Show Tôi tự hỏi liệu tôi có thể làm điều này thuận tiện hơn cho công việc của python hay không bằng cách thực thi các công cụ pbi trong tập lệnh python, để xử lý ngay các kết quả đầu ra và sau đó biên dịch lại tệp sau khi điều chỉnh. Hơn nữa, các tập lệnh yêu cầu nhiều thao tác nhập thủ công, vì vậy tôi đã thử nghiệm GUI do python tạo để đơn giản hóa việc sử dụng. Điều này không chỉ giúp tôi thuận tiện hơn mà còn là một bài tập thú vị khi suy nghĩ về thiết kế ứng dụng & trải nghiệm người dùng ngay từ đầu, thay vì trong ngữ cảnh cố định của báo cáo Power BI HƯỚNG DẪNBẠN CẦN GÌ
CHẠY POWERSHELL TỪ PYTHON (I. E. CÔNG CỤ PBI)Nói rõ hơn - Tôi không phải là chuyên gia về Python hay PowerShell. Tôi đã học cả hai để giúp tôi thực hiện một số dự án - chủ yếu là các dự án theo sở thích. Mối quan tâm của tôi là liệu tôi có thể thực thi lệnh PowerShell từ bên trong python hay không và tiếp tục sử dụng kết quả xuôi dòng Làm điều này khá dễ dàng; . Nếu bạn thực thi quy trình con. run() bạn chuyển một chuỗi dưới dạng đối số chứa
powershell = r'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' pbixpath = r'C:\Users\Klonk\Desktop\column-width_thin-report.pbix' outpath = r'C:\Users\Klonk\Desktop\pbi-tools-output\' subprocess.run(f'{powershell} pbi-tools extract {pbixpath} -extractFolder {outpath}') Tiếp tục với kết quả xuôi dòng cũng đơn giản bằng cách sử dụng đối số capture_output=True. Lưu kết quả vào một biến cũng có nghĩa là bạn có thể kiểm tra mã trả về, để xem quá trình có hoàn tất thành công hay không, như trong ví dụ dưới đây pbitools = subprocess.run(f'{powershell} pbi-tools extract {pbixpath}') if pbitools.returncode == 0: print('Success 😁') else: print('Fail 😥') Đó là khá nhiều - lưu ý rằng nếu bạn đang sử dụng quy trình con, có một số TẠO GUI TRONG PYTHON - TKINTERBây giờ chúng ta có thể thực thi các công cụ pbi từ python để dịch ngược một. báo cáo pbix. Mặc dù đây đã là thứ tôi cần, nhưng nó hơi bất tiện vì đường dẫn cần được chỉ định thủ công. Cách duy nhất để làm cho nó năng động hơn là tìm kiếm. pbix trong một thư mục nhất định - điều mà tôi không muốn làm - hoặc tạo giao diện người dùng đồ họa (GUI) cơ bản để tôi có thể chọn. tập tin pbix, bản thân tôi Tôi chưa bao giờ thử tạo GUI trước đây, vì vậy đây có vẻ là một cơ hội thú vị để thử. Tạo GUI không chỉ là một thứ gì đó thú vị cho trường hợp sử dụng cụ thể này; Có một số cách khác nhau để tạo GUI trong python; . tkinter hoạt động theo cách tương đối đơn giản; . Việc tạo các tiện ích này liên quan đến việc xác định một số chức năng có thể được gọi và tham chiếu, trong đó các chức năng có thể sửa đổi các tiện ích khác theo điều kiện. Một ví dụ về điều này có thể là nút 'OK' bị tắt cho đến khi người dùng thực hiện hành động, khi đó, tiện ích nút 'OK' được thay đổi thành trạng thái đã bật. Với các tham chiếu chéo và phụ thuộc này, thật dễ dàng để tưởng tượng rằng nó có thể nhanh chóng trở nên phức tạp (như với bất kỳ thiết kế giao diện người dùng nào)
BƯỚC 1. Khởi tạo cửa sổ. from tkinter import * from tkinter import ttk from tkinter import filedialog class GUI: def __init__(self): # Initialize the root widget self.root = Tk() # Title of the window self.root.title("Python pbi-tools") # Window colour, size & cursor self.root.configure(bg='#f3f0ea', width = 600, height = 150, cursor="hand2") # Whether the window is x, y resizable (False) self.root.resizable(False, False) # Uses display; responds to input until termination self.root.mainloop() GUI() Kết quả. Một cửa sổ trống xuất hiện trên màn hình, được định dạng như chúng tôi đã chỉ định
BƯỚC 2. Thêm một số tiện ích nhãn văn bản. from tkinter import * from tkinter import ttk from tkinter import filedialog class GUI: def __init__(self): # Initialize the root widget self.root = Tk() # Title of the window self.root.title("Python pbi-tools") # Window colour, size & cursor self.root.configure(bg='#f3f0ea', width = 600, height = 150, cursor="hand2") # Whether the window is x, y resizable (False) self.root.resizable(False, False) # Title for main window self.message = Label(self.root, text = "Select a .pbix file to decompile it with pbi-tools", font = ("Segoe UI", 14, 'bold'), fg = '#3d4244', justify = CENTER, bg='#f3f0ea') self.message.place(relheight = 0.15, relx = 0.14, rely = 0.07) # Label for the filepath row header self.LabelInputPath = Label(self.root, text = "Input .pbix: ", bg='#f3f0ea') self.LabelInputPath.place(relheight = 0.2, relx = 0.117, rely = 0.3) # Label for the filepath text self.LabelSelectedFilePath = Label(self.root, text = "Select a .pbix file to decompile.", bg='#f3f0ea') self.LabelSelectedFilePath.place(relheight = 0.2, relx = 0.23, rely = 0.3) # Label for the output path row header self.LabelOutputPath = Label(self.root, text = "Output Path: ", bg='#f3f0ea') self.LabelOutputPath.place(relheight = 0.2, relx = 0.1, rely = 0.51) # Label for the output path text self.LabelSelectedOutputPath = Label(self.root, text = "Select an output path.", bg='#f3f0ea') self.LabelSelectedOutputPath.place(relheight = 0.2, relx = 0.228, rely = 0.51) # Uses display; responds to input until termination self.root.mainloop() GUI() Càng xa càng tốt. Cú pháp đơn giản và kết quả là những gì chúng ta mong đợi Kết quả. Cửa sổ hiện có một số hướng dẫn và tiêu đề
BƯỚC 3. Thêm các nút. from tkinter import * from tkinter import ttk from tkinter import filedialog class GUI: def __init__(self): ##################### # STEP 1 ##################### # Initialize the root widget self.root = Tk() # Title of the window self.root.title("Python pbi-tools") # Window colour, size & cursor self.root.configure(bg='#f3f0ea', width = 600, height = 150, cursor="hand2") # Whether the window is x, y resizable (False) self.root.resizable(False, False) ##################### # STEP 2 ##################### # Title for main window self.message = Label(self.root, text = "Select a .pbix file to decompile it with pbi-tools", font = ("Segoe UI", 14, 'bold'), fg = '#3d4244', justify = CENTER, bg='#f3f0ea') self.message.place(relheight = 0.15, relx = 0.14, rely = 0.07) # Label for the filepath row header self.LabelInputPath = Label(self.root, text = "Input .pbix: ", bg='#f3f0ea') self.LabelInputPath.place(relheight = 0.2, relx = 0.117, rely = 0.3) # Label for the filepath text self.LabelSelectedFilePath = Label(self.root, text = "Select a .pbix file to decompile.", bg='#f3f0ea') self.LabelSelectedFilePath.place(relheight = 0.2, relx = 0.23, rely = 0.3) # Label for the output path row header self.LabelOutputPath = Label(self.root, text = "Output Path: ", bg='#f3f0ea') self.LabelOutputPath.place(relheight = 0.2, relx = 0.1, rely = 0.51) # Label for the output path text self.LabelSelectedOutputPath = Label(self.root, text = "Select an output path.", bg='#f3f0ea') self.LabelSelectedOutputPath.place(relheight = 0.2, relx = 0.228, rely = 0.51) ##################### # STEP 3 ##################### # Input File Browse button self.button_input_browse = ttk.Button(self.root, text = "Browse...") self.button_input_browse.place(relx = 0.53, rely = 0.315) # Output Path Browse button self.button_output_browse = ttk.Button(self.root, text = "Browse...") self.button_output_browse.place(relx = 0.53, rely = 0.52) # Cancel button self.browse_button = ttk.Button(self.root, text = "Cancel") self.browse_button.place(relx = 0.73, rely = 0.8) # Add OK button self.button_OK = ttk.Button(self.root, text = "OK") self.button_OK.place(relx = 0.865, rely = 0.8) ##################### # Uses display; responds to input until termination ##################### self.root.mainloop() GUI() Kết quả. Các nút, nhưng chúng chưa làm gì cả
BƯỚC 4. Xác định chức năng cho các nút lệnh. Chúng tôi có 4 nút và chúng tôi muốn mỗi nút làm một việc khác nhau
##################### # Input .pbix browse button ##################### def get_file_path(self): # Set global file_path var global file_path # Open file dialog accepting only .pbix files; path will be the file_path var file_path= filedialog.askopenfilename(title = "Select A File", filetypes = [("pbix files", "*.pbix")]) ##################### # Step 5: Modify existing widgets ##################### # Hide button after push self.button_input_browse.place_forget() # Update text label with file path self.LabelSelectedFilePath.config(text=file_path, bg='#f3f0ea') # Update 'OK' button state once the file dialog is done self.button_OK["state"] = NORMAL
##################### # Output path browse button ##################### def get_output_path(self): # Set global file_path var global output_path # Open and return file path as file_path var output_path = filedialog.askdirectory(title = "Select An Output Destination") + f'/pbi-tools-output' ##################### # Step 5: Modify existing widgets ##################### # Hide button after push self.button_output_browse.place_forget() # Update text label with file path self.LabelSelectedOutputPath.config(text=output_path, bg='#f3f0ea')
##################### # Cancel button ##################### def cancel(self): self.root.destroy() exit()
________số 8
Kết quả. Trước khi chọn một. pbix và đường dẫn đầu ra Kết quả. Sau khi chọn một. pbix và đường dẫn đầu ra
BƯỚC 6. Sử dụng các biến toàn cầu xuôi dòng trong phần còn lại của tập lệnh. Đầu ra cuối cùng; Bây giờ tôi có thể chạy các công cụ pbi từ bên trong python và sử dụng đầu ra cho các hành động lập trình xuôi dòng khác KẾT LUẬN
|