excel - C# WinUI 3 我无法使用 FileSavePicker 对话框中指定的文件来创建 Excel 报告文件

标签 excel file asynchronous winui-3 filesavepicker

我的第一个 WinUI 3 项目。我的第二个 C# 项目。我已经能够让 FileSavePicker 工作并显示一个对话框:
我要展示的是一个 stub 程序,它只是为了解决我在使用 FileSavePicker 时遇到的问题而创建的。
问题描述:我不知道如何将非异步方法“CreateReport()”与异步 FileSavePicker 一起使用。
我已经使用“创建报告”按钮测试了 CreateReport() 方法,它成功创建了一个 excel 文件并成功写入该文件(使用 EPPlus)。
如何使 CreateReport() 方法等待 FileSavePicker 完成,然后使用 FileSavePicker 中的 file.name?
我尝试生成一个 excel 文件,但是当我尝试打开该文件时,excel 给了我这个错误:
enter image description here
主窗口:
enter image description here
XAML:

<Window
    x:Class="App_WinUI3_FileSavePicker_Sandbox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App_WinUI3_FileSavePicker_Sandbox"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center" Width="800" BorderBrush="black" BorderThickness="8">

        <TextBlock Text="Test of File Save Picker and Creating an Excel file" HorizontalAlignment="Center" Margin="10" FontSize="20"/>

        <StackPanel Orientation="Horizontal">

            <Button x:Name="myButton" Click="myButton_Click" Margin="10" Padding="10">Start File Save Picker</Button>

            <Button x:Name="Button2" Click="Button2_Click"  Margin="10" Padding="10" ToolTipService.ToolTip="Tests the creation of an excel file using a hardcoded filename and not using the File Save Picker" >Create Report</Button>

        </StackPanel>

        <TextBox x:Name="ReportStatus1"  Header="Report Status 1" Margin="10" FontSize="20"/>

        <TextBox x:Name="ReportStatus2"  Header="Report Status 2" Margin="10" FontSize="20"/>

        <TextBox x:Name="ReportStatus3"  Header="Report Status 3" Margin="10" FontSize="20"/>

        <TextBox x:Name="ReportStatus4"  Header="Report Status 4" Margin="10" FontSize="20"/>

        <TextBox x:Name="ReportStatus5"  Header="Report Status 5" Margin="10" FontSize="20"/>
    </StackPanel>
</Window>
后面的 C# 代码
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Provider;
using OfficeOpenXml;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace App_WinUI3_FileSavePicker_Sandbox
{
    /// <summary>
    /// An empty window that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
            // Retrieve the window handle (HWND) of the current WinUI 3 window.
            var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
            // For EPPlus spreadsheet library for .NET         
            ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
        }

        public string File_Name = string.Empty;

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            DisplayReportSaveDialog("Report1");
            CreateReport(File_Name);
        }

        private async void DisplayReportSaveDialog(string ReportName)
        {
            FileSavePicker savePicker = new FileSavePicker();

            // Retrieve the window handle (HWND) of the current WinUI 3 window.
            var window = (Application.Current as App)?.m_window as MainWindow;
            var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window);

            // Initialize the folder picker with the window handle (HWND).
            WinRT.Interop.InitializeWithWindow.Initialize(savePicker, hWnd);

            savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;

            // Dropdown of file types the user can save the file as
            savePicker.FileTypeChoices.Add("Excel Workbook", new List<string>() { ".xlsx" });
            // I don't want a text file.  I need to create an excel file. 
            // savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt" });

            // Default file name if the user does not type one in or select a file to replace
            switch (ReportName)
            {
                case "Report1":
                    savePicker.SuggestedFileName = "Report1_" + String.Format("{0:MMddyyyy_HHmmss}", DateTime.Now) + ".xlsx";
                    break;
                case "Report2":
                    savePicker.SuggestedFileName = "Report2_" + String.Format("{0:MMddyyyy_HHmmss}", DateTime.Now) + ".xlsx";
                    break;
            }

            // Display the file picker dialog by calling PickSaveFileAsync
            StorageFile file = await savePicker.PickSaveFileAsync();
            if (file != null)
            {
                // Prevent updates to the remote version of the file until we finish making changes and call CompleteUpdatesAsync.
                CachedFileManager.DeferUpdates(file);

                // write the file name into the file.  
                // This is the sample code from the microsoft docs. 
                // It shows how to write simple text to a text file. 
                // It does work. 
                // Is there a similar way I can do this with my method 'CreateReport()'?

                //await FileIO.WriteTextAsync(file, file.Name);

                // Let Windows know that we're finished changing the file so the other app can update the remote version of the file.
                // Completing updates may require Windows to ask for user input.

                File_Name = file.Name;

                // What does this do?  
                // Why did I add this? 
                //await file.DeleteAsync(); 

                ReportStatus3.Text = $"path = {file.Path}";
                ReportStatus4.Text = $"file_Name = {File_Name}";

                FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
                if (status == FileUpdateStatus.Complete)
                {
                    ReportStatus1.Text = "File " + file.Name + " was saved....";
                }
                else
                {
                    ReportStatus1.Text = "File " + file.Name + " couldn't be saved.";
                }
            }
            else
            {
                ReportStatus2.Text = $"{ReportName} report cancelled.";
            }
        }

        private void CreateReport(string filename)
        {
            try
            {
                filename = "c:\\sandbox\\" + filename;
                ReportStatus5.Text = $"filename = {filename} - Message from (CreateReport())";
                using (var package = new ExcelPackage(filename))
                {
                    // EPPLUS - Add a new worksheet. 
                    var ws = package.Workbook.Worksheets.Add($"EMB High Level Goals");
                    ws.Cells["A1"].Value = "1";
                    ws.Cells["A2"].Value = "2";
                    ws.Cells["B1"].Value = "Lenny";
                    ws.Cells["B2"].Value = "Created by App_WinUI3_FileSavePicker_Sandbox";
                    package.Save();

                } // end using

                ReportStatus3.Text = $"CreateReport: File {filename} was saved....";

            }
            catch (Exception e)
            {
                ReportStatus4.Text = $"CreateReport error: {e.Message}";
            }
        }

        private void Button2_Click(object sender, RoutedEventArgs e)
        {
            string filename = "Test_Report_" + String.Format("{0:MMddyyyy_HHmmss}", DateTime.Now) + ".xlsx";
            CreateReport(filename);
        }
    }
}

最佳答案

只需删除评论的 Microsoft 内容:

//await FileIO.WriteTextAsync(file, file.Name);

//await file.DeleteAsync(); 
而不是调用你自己的函数:
CreateReport(file.Name);

关于excel - C# WinUI 3 我无法使用 FileSavePicker 对话框中指定的文件来创建 Excel 报告文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71792862/

相关文章:

excel - Excel VBA中是否有办法在创建数组时使用两个字符函数

c - 将用户输入写入文件,然后读取它

node.js - NodeJS,从async wait获取返回值

asynchronous - 如何以严格的顺序使用 AFNetworking 2 发送请求?

c# - 为什么 xls 在从代码读取时/之后打开?

python - Excel - 查找前一行和各种范围大小的最大值

.net - itgenclr007 : Fix OutOfMemory in 32-bit Excel with VSTO add-in

c - 生成具有漂亮文件名的临时文件的 POSIX 方法

C++ 从包含字符的文件中读取数字

c++ - gRPC cpp 异步服务器与同步服务器