使用SpreadsheetGear在UWP及Xamarin.Forms中指定路径保存Excel工作簿问题
UWP 中使用 SpreadsheetGear 保存 Excel 工作簿到指定路径
UWP 存在沙箱权限限制,直接写入任意路径可能失败,需根据目标位置选择对应方案:
1. 保存到应用本地文件夹(无需额外权限)
文件会存储在应用专属的沙箱目录,无需额外配置:
// 假设已创建 SpreadsheetGear.IWorkbook 实例 IWorkbook workbook = Factory.GetWorkbook(); string localFolderPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path; string fullFilePath = Path.Combine(localFolderPath, "SavedExcel.xlsx"); // 调用 SpreadsheetGear 的 SaveAs 方法完成保存 workbook.SaveAs(fullFilePath, FileFormat.OpenXmlWorkbook);
2. 保存到系统文档库(需配置权限)
若要保存到系统文档库,先在 Package.appxmanifest 中配置:
- 切换到「功能」标签,勾选「文档库」
- 切换到「声明」标签,添加「文件类型关联」,指定
.xlsx等 Excel 格式
之后用以下代码保存:
IWorkbook workbook = Factory.GetWorkbook(); // 获取系统文档库 StorageFolder docsFolder = KnownFolders.DocumentsLibrary; // 创建或覆盖目标文件 StorageFile targetFile = await docsFolder.CreateFileAsync("SavedExcel.xlsx", CreationCollisionOption.ReplaceExisting); // 通过流写入内容 using (var writeStream = await targetFile.OpenStreamForWriteAsync()) { workbook.SaveToStream(writeStream, FileFormat.OpenXmlWorkbook); }
3. 让用户选择保存路径(文件选择器)
如果需要用户自定义保存位置,用 UWP 自带的 FileSavePicker:
IWorkbook workbook = Factory.GetWorkbook(); var savePicker = new FileSavePicker(); savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; savePicker.FileTypeChoices.Add("Excel 工作簿", new List<string> { ".xlsx" }); savePicker.SuggestedFileName = "SavedExcel"; StorageFile selectedFile = await savePicker.PickSaveFileAsync(); if (selectedFile != null) { using (var writeStream = await selectedFile.OpenStreamForWriteAsync()) { workbook.SaveToStream(writeStream, FileFormat.OpenXmlWorkbook); } }
Xamarin.Forms 中保存文件到指定文件夹
Xamarin.Forms 跨平台保存需适配不同平台的文件系统规则,推荐用依赖服务实现各平台的具体逻辑:
1. 定义共享接口
在共享项目中创建文件保存接口:
public interface IFileSaver { Task SaveFileAsync(string fileName, Stream fileStream, string targetFolderPath = null); }
2. 各平台实现
UWP 平台
[assembly: Dependency(typeof(UwpFileSaver))] namespace YourApp.UWP { public class UwpFileSaver : IFileSaver { public async Task SaveFileAsync(string fileName, Stream fileStream, string targetFolderPath = null) { StorageFile targetFile; if (string.IsNullOrEmpty(targetFolderPath)) { // 默认保存到文档库 StorageFolder docsFolder = KnownFolders.DocumentsLibrary; targetFile = await docsFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); } else { // 保存到指定文件夹(需确保应用有权限访问) StorageFolder targetFolder = await StorageFolder.GetFolderFromPathAsync(targetFolderPath); targetFile = await targetFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); } using (var writeStream = await targetFile.OpenStreamForWriteAsync()) { await fileStream.CopyToAsync(writeStream); await writeStream.FlushAsync(); } } } }
Android 平台
注意 Android 10+ 需适配 Scoped Storage,或申请 MANAGE_EXTERNAL_STORAGE 权限(Android 11+):
[assembly: Dependency(typeof(AndroidFileSaver))] namespace YourApp.Droid { public class AndroidFileSaver : IFileSaver { public async Task SaveFileAsync(string fileName, Stream fileStream, string targetFolderPath = null) { string fullFilePath; if (string.IsNullOrEmpty(targetFolderPath)) { // 默认保存到外部存储的文档目录 var docsDir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments); fullFilePath = Path.Combine(docsDir.AbsolutePath, fileName); } else { fullFilePath = Path.Combine(targetFolderPath, fileName); } using (var writeStream = new FileStream(fullFilePath, FileMode.Create)) { await fileStream.CopyToAsync(writeStream); await writeStream.FlushAsync(); } } } }
iOS 平台
iOS 应用仅能访问自身沙箱目录,若需让用户在文件应用中查看,可通过 UIDocumentInteractionController 分享:
[assembly: Dependency(typeof(IosFileSaver))] namespace YourApp.iOS { public class IosFileSaver : IFileSaver { public async Task SaveFileAsync(string fileName, Stream fileStream, string targetFolderPath = null) { string fullFilePath; if (string.IsNullOrEmpty(targetFolderPath)) { // 默认保存到应用文档目录 var docsDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); fullFilePath = Path.Combine(docsDir, fileName); } else { fullFilePath = Path.Combine(targetFolderPath, fileName); } using (var writeStream = new FileStream(fullFilePath, FileMode.Create)) { await fileStream.CopyToAsync(writeStream); await writeStream.FlushAsync(); } // 弹出菜单让用户选择打开/保存方式 var fileUrl = new NSUrl(fullFilePath, false); var docController = UIDocumentInteractionController.FromUrl(fileUrl); docController.PresentOpenInMenu(null, null, null, null); } } }
3. 在共享项目中调用
// 示例:从 SpreadsheetGear 获取 Excel 流 IWorkbook workbook = Factory.GetWorkbook(); var excelStream = new MemoryStream(); workbook.SaveToStream(excelStream, FileFormat.OpenXmlWorkbook); excelStream.Position = 0; // 调用依赖服务保存文件 await DependencyService.Get<IFileSaver>().SaveFileAsync("SavedExcel.xlsx", excelStream);
内容的提问来源于stack exchange,提问作者ProgramacionFJ
相关产品推荐
相关产品推荐

