From 90524c1915854cf575b47f2880254d830c56e078 Mon Sep 17 00:00:00 2001 From: Alberto Spelta Date: Mon, 2 Mar 2026 14:26:10 +0100 Subject: [PATCH 1/2] Bump LargeXlsx from 1.10.0 to 2.0.1 --- src/Bravo.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bravo.csproj b/src/Bravo.csproj index 8398b862..fec3c48d 100644 --- a/src/Bravo.csproj +++ b/src/Bravo.csproj @@ -62,7 +62,7 @@ - + From faa71b7af5a5575f631c964064c8b31efa1f63aa Mon Sep 17 00:00:00 2001 From: Alberto Spelta Date: Mon, 2 Mar 2026 14:52:06 +0100 Subject: [PATCH 2/2] Remove useZip64 option for XLSX export The export library (LargeXlsx) dropped its SharpCompress dependency and now uses System.IO.Compression. SharpCompress did not fully support Zip64 and could produce corrupted Excel/LibreOffice files. --- src/Controllers/ExportDataController.cs | 8 ++------ src/Services/ExportDataService.cs | 23 ++++++++--------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/Controllers/ExportDataController.cs b/src/Controllers/ExportDataController.cs index 1f31b5ca..a2247bad 100644 --- a/src/Controllers/ExportDataController.cs +++ b/src/Controllers/ExportDataController.cs @@ -106,11 +106,9 @@ public async Task ExportDelimitedTextFile(ExportDelimitedTextFrom [ProducesDefaultResponseType] public IActionResult ExportExcelFile(ExportExcelFromPBIReportRequest request, CancellationToken cancellationToken) { - var useZip64 = CommonHelper.IsKeyDown(System.Windows.Forms.Keys.ControlKey); - if (WindowDialogHelper.SaveFileDialog(fileName: request.Report!.ReportName, filter: null, defaultExt: "XLSX", out var path, cancellationToken)) { - var job = _exportDataService.ExportExcelFile(request.Report, request.Settings!, path, useZip64, cancellationToken); + var job = _exportDataService.ExportExcelFile(request.Report, request.Settings!, path, cancellationToken); return Ok(job); } @@ -132,14 +130,12 @@ public IActionResult ExportExcelFile(ExportExcelFromPBIReportRequest request, Ca [ProducesDefaultResponseType] public async Task ExportExcelFile(ExportExcelFromPBICloudDatasetRequest request, CancellationToken cancellationToken) { - var useZip64 = CommonHelper.IsKeyDown(System.Windows.Forms.Keys.ControlKey); - if (await _authenticationService.IsPBICloudSignInRequiredAsync(cancellationToken)) return Unauthorized(); if (WindowDialogHelper.SaveFileDialog(fileName: request.Dataset!.DisplayName, filter: null, defaultExt: "XLSX", out var path, cancellationToken)) { - var job = _exportDataService.ExportExcelFile(request.Dataset, request.Settings!, path, _authenticationService.PBICloudAuthentication.AccessToken, useZip64, cancellationToken); + var job = _exportDataService.ExportExcelFile(request.Dataset, request.Settings!, path, _authenticationService.PBICloudAuthentication.AccessToken, cancellationToken); return Ok(job); } diff --git a/src/Services/ExportDataService.cs b/src/Services/ExportDataService.cs index e2d8b5f1..d6ed43ba 100644 --- a/src/Services/ExportDataService.cs +++ b/src/Services/ExportDataService.cs @@ -27,9 +27,9 @@ public interface IExportDataService ExportDataJob ExportDelimitedTextFile(PBICloudDataset dataset, ExportDelimitedTextSettings settings, string path, string accessToken, CancellationToken cancellationToken); - ExportDataJob ExportExcelFile(PBIDesktopReport report, ExportExcelSettings settings, string path, bool useZip64, CancellationToken cancellationToken); + ExportDataJob ExportExcelFile(PBIDesktopReport report, ExportExcelSettings settings, string path, CancellationToken cancellationToken); - ExportDataJob ExportExcelFile(PBICloudDataset dataset, ExportExcelSettings settings, string path, string accessToken, bool useZip64, CancellationToken cancellationToken); + ExportDataJob ExportExcelFile(PBICloudDataset dataset, ExportExcelSettings settings, string path, string accessToken, CancellationToken cancellationToken); ExportDataJob? QueryExportJob(PBIDesktopReport report); @@ -110,7 +110,7 @@ public ExportDataJob ExportDelimitedTextFile(PBICloudDataset dataset, ExportDeli return job; } - public ExportDataJob ExportExcelFile(PBIDesktopReport report, ExportExcelSettings settings, string path, bool useZip64, CancellationToken cancellationToken) + public ExportDataJob ExportExcelFile(PBIDesktopReport report, ExportExcelSettings settings, string path, CancellationToken cancellationToken) { settings.ExportPath = path; @@ -119,7 +119,7 @@ public ExportDataJob ExportExcelFile(PBIDesktopReport report, ExportExcelSetting { using var connection = AdomdConnectionWrapper.ConnectTo(report); - ExportExcelFileImpl(job, settings, connection, useZip64, cancellationToken); + ExportExcelFileImpl(job, settings, connection, cancellationToken); job.SetCompleted(); } catch (OperationCanceledException) @@ -139,7 +139,7 @@ public ExportDataJob ExportExcelFile(PBIDesktopReport report, ExportExcelSetting return job; } - public ExportDataJob ExportExcelFile(PBICloudDataset dataset, ExportExcelSettings settings, string path, string accessToken, bool useZip64, CancellationToken cancellationToken) + public ExportDataJob ExportExcelFile(PBICloudDataset dataset, ExportExcelSettings settings, string path, string accessToken, CancellationToken cancellationToken) { settings.ExportPath = path; @@ -148,7 +148,7 @@ public ExportDataJob ExportExcelFile(PBICloudDataset dataset, ExportExcelSetting { using var connection = AdomdConnectionWrapper.ConnectTo(dataset, accessToken); - ExportExcelFileImpl(job, settings, connection, useZip64, cancellationToken); + ExportExcelFileImpl(job, settings, connection, cancellationToken); job.SetCompleted(); } catch (OperationCanceledException) @@ -303,7 +303,7 @@ static int WriteData(ExportDataTable table, CsvWriter writer, IDataReader reader } } - private static void ExportExcelFileImpl(ExportDataJob job, ExportExcelSettings settings, AdomdConnectionWrapper connection, bool useZip64, CancellationToken cancellationToken) + private static void ExportExcelFileImpl(ExportDataJob job, ExportExcelSettings settings, AdomdConnectionWrapper connection, CancellationToken cancellationToken) { var xlsxFile = new FileInfo(settings.ExportPath); @@ -313,15 +313,8 @@ private static void ExportExcelFileImpl(ExportDataJob job, ExportExcelSettings s using var command = connection.CreateAdomdCommand(); using var _ = cancellationToken.Register(() => command.Cancel()); - if (useZip64 && AppEnvironment.IsDiagnosticLevelVerbose) - { - // Zip64 is an experimental feature in Bravo that must be explicitly enabled by the user and is not enabled by default because it may create a file that Excel or LibreOffice reports as corrupt. - // See https://github.com/salvois/LargeXlsx/issues/3#issuecomment-867675374 and https://github.com/salvois/LargeXlsx/issues/5#issuecomment-981072044 - AppEnvironment.AddDiagnostics(DiagnosticMessageType.Text, name: $"{nameof(ExportDataService)}.{nameof(ExportExcelFileImpl)}", content: $"Experimental feature: useZip64 is enabled"); - } - using var fileStream = new FileStream(xlsxFile.FullName, FileMode.Create, FileAccess.Write); - using var xlsxWriter = new XlsxWriter(fileStream, useZip64: useZip64); + using var xlsxWriter = new XlsxWriter(fileStream, compressionLevel: XlsxCompressionLevel.Fastest); foreach (var (tableName, tableIndex) in settings.Tables.WithIndex()) {