From 8f60e780486d841278ad74cf02c4fe46595c5524 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 21 Jun 2025 18:31:50 +0800 Subject: [PATCH 1/7] feat(exporter): Add a PDF export module - Add the integration of [LibreOffice](https://www.libreoffice.org) PDF export - Add the integration of [Spire.XLS](https://www.e-iceblue.cn/spirexls/spire-xls-for-net-program-guide-content.html) PDF export --- .../LINGYUN.Abp.Exporter.Core.csproj | 5 +- .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 +++++ ...INGYUN.Abp.Exporter.Pdf.LibreOffice.csproj | 21 ++++ .../AbpExporterPdfLibreOfficeModule.cs | 17 +++ .../Pdf/LibreOffice/LibreOfficeCommands.cs | 103 ++++++++++++++++++ .../LibreOfficeExcelToPdfProvider.cs | 52 +++++++++ .../README.md | 26 +++++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 +++++ .../LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj | 25 +++++ .../SpireLib/AbpExporterPdfSpireLibModule.cs | 13 +++ .../Pdf/SpireLib/SpireExcelToPdfProvider.cs | 20 ++++ .../README.md | 25 +++++ .../LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml | 3 + .../LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xsd | 30 +++++ .../LINGYUN.Abp.Exporter.Pdf.csproj | 21 ++++ .../Abp/Exporter/Pdf/AbpExporterPdfModule.cs | 8 ++ .../Abp/Exporter/Pdf/IExcelToPdfProvider.cs | 10 ++ .../Exporter/Pdf/NullExcelToPdfProvider.cs | 16 +++ .../LINGYUN.Abp.Exporter.Pdf/README.md | 38 +++++++ 21 files changed, 496 insertions(+), 3 deletions(-) create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xsd create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN.Abp.Exporter.Pdf.LibreOffice.csproj create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeCommands.cs create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeExcelToPdfProvider.cs create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/README.md create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xsd create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibModule.cs create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/SpireExcelToPdfProvider.cs create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/README.md create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xsd create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN.Abp.Exporter.Pdf.csproj create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfModule.cs create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/IExcelToPdfProvider.cs create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/NullExcelToPdfProvider.cs create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/README.md diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/LINGYUN.Abp.Exporter.Core.csproj b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/LINGYUN.Abp.Exporter.Core.csproj index 1c7593897..34b1d5c30 100644 --- a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/LINGYUN.Abp.Exporter.Core.csproj +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/LINGYUN.Abp.Exporter.Core.csproj @@ -15,12 +15,11 @@ - + - - + diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml new file mode 100644 index 000000000..00e1d9a1c --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xsd b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN.Abp.Exporter.Pdf.LibreOffice.csproj b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN.Abp.Exporter.Pdf.LibreOffice.csproj new file mode 100644 index 000000000..b14819d8c --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN.Abp.Exporter.Pdf.LibreOffice.csproj @@ -0,0 +1,21 @@ + + + + + + + net8.0;net9.0 + LINGYUN.Abp.Exporter.Pdf.LibreOffice + LINGYUN.Abp.Exporter.Pdf.LibreOffice + false + false + false + enable + + + + + + + + diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs new file mode 100644 index 000000000..d686cbc12 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; + +[DependsOn(typeof(AbpExporterPdfModule))] +public class AbpExporterPdfLibreOfficeModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + if (!LibreOfficeCommands.IsLibreOffliceInstalled()) + { + throw new Volo.Abp.AbpInitializationException("Libreoffice not installed in the current operation environment of the host, please refer to the document after installation using ` AbpExporterPdfLibreOfficeModule ` module."); + } + context.Services.AddTransient(); + } +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeCommands.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeCommands.cs new file mode 100644 index 000000000..5209364f6 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeCommands.cs @@ -0,0 +1,103 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; + +public class LibreOfficeCommands +{ + public static string WindowsCli { get; set; } = "soffice.com"; + public static string WindowsCliDir { get; set; } = "C:\\Program Files\\LibreOffice\\program\\"; + + public static string UnixCli { get; set; } = "libreoffice"; + public static string UnixCliDir { get; set; } = ""; + + public static string GetCli() + { + if (OperatingSystem.IsWindows()) + { + return Path.Combine(WindowsCliDir, WindowsCli); + } + + // 详细的操作系统版本: https://zh-cn.libreoffice.org/get-help/system-requirements/ + if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + { + return Path.Combine(UnixCliDir, UnixCli); + } + + throw new PlatformNotSupportedException($"The current platform {Environment.OSVersion.ToString()} does not support the libreoffice runtime library"); + } + + public static bool IsLibreOffliceInstalled() + { + return LibreOfficeCommands.IsLibreOfficeAvailable(GetCli()); + } + /// + /// LibreOffice是否可用 + /// + /// + /// + public static bool IsLibreOfficeAvailable(string commandFile) + { + try + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = commandFile, + Arguments = "--version", + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + } + }; + + process.Start(); + var output = process.StandardOutput.ReadToEnd(); + + process.WaitForExit(); + + return process.ExitCode == 0 && output.Contains("LibreOffice"); + } + catch + { + return false; + } + } + /// + /// Excel转换为Pdf + /// + /// + /// + /// + public async static Task ExcelToPdf(string excelFile, string outputPath, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + + var start = new ProcessStartInfo + { + FileName = GetCli(), + Arguments = $"--headless --convert-to pdf \"{excelFile}\" --outdir \"{outputPath}\"", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + }; + + var process = new Process + { + StartInfo = start, + }; + process.Start(); + + await process.WaitForExitAsync(cancellationToken); + + if (process.ExitCode != 0) + { + throw new Exception($"Excel failed to convert to PDF. Error code: {process.ExitCode}"); + } + } +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeExcelToPdfProvider.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeExcelToPdfProvider.cs new file mode 100644 index 000000000..0241e0d03 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeExcelToPdfProvider.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.IO; + +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; +public class LibreOfficeExcelToPdfProvider : IExcelToPdfProvider +{ + public async virtual Task ParseAsync(Stream excelStream, CancellationToken cancellationToken = default) + { + var outputPath = Path.Combine(Path.GetTempPath(), "excel2pdf"); + + DirectoryHelper.CreateIfNotExists(outputPath); + + var templateFileId = Guid.NewGuid().ToString(); + var tempExcelFile = Path.Combine(outputPath, $"{templateFileId}.xlsx"); + var tempPdfFile = Path.Combine(outputPath, $"{templateFileId}.pdf"); + + try + { + if (!File.Exists(tempExcelFile)) + { + using (var excelFile = File.Create(tempExcelFile)) + { + await excelStream.CopyToAsync(excelFile, cancellationToken); + } + } + + await LibreOfficeCommands.ExcelToPdf(tempExcelFile, outputPath, cancellationToken); + + var pdfStream = new MemoryStream(); + + using (var pdfFileStream = File.OpenRead(tempPdfFile)) + { + await pdfFileStream.CopyToAsync(pdfStream, cancellationToken); + pdfStream.Seek(0, SeekOrigin.Begin); + } + + return pdfStream; + } + catch + { + throw; + } + finally + { + FileHelper.DeleteIfExists(tempExcelFile); + FileHelper.DeleteIfExists(tempPdfFile); + } + } +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/README.md b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/README.md new file mode 100644 index 000000000..8af96eb9f --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/README.md @@ -0,0 +1,26 @@ +# LINGYUN.Abp.Exporter.Pdf.LibreOffice + +> LibreOffice is Free and Open Source Software. Development is open to new talent and new ideas, and our software is tested and used daily by a large and devoted user community. + +此模块使用本地 `LibreOffice` 命令行实现将Excel转换为Pdf, 请引用此模块前确保已安装有 `LibreOffice`, 如未安装在默认目录, 请在使用前手动指定安装目录. + +## 配置使用 + + +```csharp + + [DependsOn( + typeof(AbpExporterPdfLibreOfficeModule) + )] + public class YouProjectModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + // 手动指定安装目录 + LibreOfficeCommands.WindowsCliDir = "path\\to\\libreoffice"; + LibreOfficeCommands.UnixCliDir = "path/to/libreoffice"; + } + } +``` + + diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml new file mode 100644 index 000000000..00e1d9a1c --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xsd b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj new file mode 100644 index 000000000..0935705a0 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj @@ -0,0 +1,25 @@ + + + + + + + net8.0;net9.0 + LINGYUN.Abp.Exporter.Pdf.SpireLib + LINGYUN.Abp.Exporter.Pdf.SpireLib + false + false + false + enable + + + + + + + + + + + + diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibModule.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibModule.cs new file mode 100644 index 000000000..fa3d1d0b7 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibModule.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Exporter.Pdf.SpireLib; + +[DependsOn(typeof(AbpExporterPdfModule))] +public class AbpExporterPdfSpireLibModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddTransient(); + } +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/SpireExcelToPdfProvider.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/SpireExcelToPdfProvider.cs new file mode 100644 index 000000000..217709507 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/SpireExcelToPdfProvider.cs @@ -0,0 +1,20 @@ +using Spire.Xls; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Exporter.Pdf.SpireLib; + +public class SpireExcelToPdfProvider : IExcelToPdfProvider +{ + public virtual Task ParseAsync(Stream excelStream, CancellationToken cancellationToken = default) + { + using var workBook = new Workbook(); + Stream memoryStream = new MemoryStream(); + workBook.LoadFromStream(excelStream); + var workSheet = workBook.Worksheets[0]; + workSheet.SaveToPdfStream(memoryStream); + + return Task.FromResult(memoryStream); + } +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/README.md b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/README.md new file mode 100644 index 000000000..526cedb73 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/README.md @@ -0,0 +1,25 @@ +# LINGYUN.Abp.Exporter.Pdf.SpireLib + +> Spire.XLS for .NET 是一款专业的 .NET Excel 组件, 它可以用在各种 .NET 框架中,包括 .NET Core、.NET 5.0、.NET 6.0、.NET 7.0、.NET Standard、 Xamarin、Mono Android、ASP.NET 和 Windows Forms 等相关的 .NET 应用程序。Spire.XLS for .NET 提供了一个对象模型 Excel API,使开发人员可以快速地在 .NET 平台上完成对 Excel 的各种编程操作,如根据模板创建新的 Excel 文档,编辑现有 Excel 文档以及对 Excel 文档进行转换。 + +此模块使用 [Spire.XLS](https://www.e-iceblue.cn/spirexls/spire-xls-for-net-program-guide-content.html) 实现将Excel转换为Pdf,请在使用前配置许可. + +## 配置使用 + + +```csharp + + [DependsOn( + typeof(AbpExporterPdfModule) + )] + public class YouProjectModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + // 配置许可 + Spire.Xls.License.LicenseProvider.SetLicense("xxx"); + } + } +``` + + diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml new file mode 100644 index 000000000..00e1d9a1c --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xsd b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN.Abp.Exporter.Pdf.csproj b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN.Abp.Exporter.Pdf.csproj new file mode 100644 index 000000000..b2f7aee0f --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN.Abp.Exporter.Pdf.csproj @@ -0,0 +1,21 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0;net9.0 + LINGYUN.Abp.Exporter.Pdf + LINGYUN.Abp.Exporter.Pdf + false + false + false + enable + + + + + + + + diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfModule.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfModule.cs new file mode 100644 index 000000000..ee07ff723 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfModule.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Exporter.Pdf; + +public class AbpExporterPdfModule : AbpModule +{ + +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/IExcelToPdfProvider.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/IExcelToPdfProvider.cs new file mode 100644 index 000000000..93cd59d11 --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/IExcelToPdfProvider.cs @@ -0,0 +1,10 @@ +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Exporter.Pdf; + +public interface IExcelToPdfProvider +{ + Task ParseAsync(Stream excelStream, CancellationToken cancellationToken = default); +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/NullExcelToPdfProvider.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/NullExcelToPdfProvider.cs new file mode 100644 index 000000000..293adf18e --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/NullExcelToPdfProvider.cs @@ -0,0 +1,16 @@ +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.Exporter.Pdf; + +[Dependency(TryRegister = true)] +public class NullExcelToPdfProvider : IExcelToPdfProvider, ISingletonDependency +{ + private readonly static Stream _nullStreamCache = Stream.Null; + public virtual Task ParseAsync(Stream excelStream, CancellationToken cancellationToken = default) + { + return Task.FromResult(_nullStreamCache); + } +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/README.md b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/README.md new file mode 100644 index 000000000..9ac74054d --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/README.md @@ -0,0 +1,38 @@ +# LINGYUN.Abp.Exporter.Pdf + +Pdf导出模块 + +## 配置使用 + + +```csharp + + [DependsOn( + typeof(AbpExporterPdfModule) + )] + public class YouProjectModule : AbpModule + { + + } +``` + +> 导出数据 +```csharp + public class ExportDemoClass + { + private readonly IExcelToPdfProvider _exporterProvider; + + public ExportDemoClass(IExcelToPdfProvider exporterProvider) + { + _exporterProvider = exporterProvider; + } + + public async virtual Task ExportAsync(Stream excelStream) + { + var stream = await _exporterProvider.ParseAsync(excelStream); + + return new RemoteStreamContent(stream, "demo.pdf"); + } + } +``` + From 317c2f7f49cd0bcf2ce7382925e19733622befbc Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 21 Jun 2025 18:33:58 +0800 Subject: [PATCH 2/7] fix(exporter): update `FodyWeavers.xml` --- .../exporter/LINGYUN.Abp.Exporter.Core/FodyWeavers.xml | 4 ++-- .../LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml | 4 ++-- .../LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml | 4 ++-- .../exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/FodyWeavers.xml b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/FodyWeavers.xml index 00e1d9a1c..1715698cc 100644 --- a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/FodyWeavers.xml +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/FodyWeavers.xml @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml index 00e1d9a1c..1715698cc 100644 --- a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml index 00e1d9a1c..1715698cc 100644 --- a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml index 00e1d9a1c..1715698cc 100644 --- a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml @@ -1,3 +1,3 @@ - - + + \ No newline at end of file From 9c4a2c98b2b92ff73cd0e876cbaed99bf1324c44 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 21 Jun 2025 18:37:09 +0800 Subject: [PATCH 3/7] feat(exporter): Remove the redundant fields - Removed from ` MagicodesIEExcelExporterProvider ` ` IExcelExporter ` references --- .../LINGYUN/Abp/Exporter/MagicodesIEExcelExporterProvider.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.MagicodesIE.Excel/LINGYUN/Abp/Exporter/MagicodesIEExcelExporterProvider.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.MagicodesIE.Excel/LINGYUN/Abp/Exporter/MagicodesIEExcelExporterProvider.cs index 7ce8fefa2..cae49824b 100644 --- a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.MagicodesIE.Excel/LINGYUN/Abp/Exporter/MagicodesIEExcelExporterProvider.cs +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.MagicodesIE.Excel/LINGYUN/Abp/Exporter/MagicodesIEExcelExporterProvider.cs @@ -1,5 +1,4 @@ -using Magicodes.ExporterAndImporter.Excel; -using Magicodes.ExporterAndImporter.Excel.Utility; +using Magicodes.ExporterAndImporter.Excel.Utility; using Microsoft.Extensions.Options; using System.Collections.Generic; using System.IO; @@ -12,7 +11,6 @@ namespace LINGYUN.Abp.Exporter.MagicodesIE.Excel; public class MagicodesIEExcelExporterProvider : IExporterProvider, ITransientDependency { private readonly AbpExporterMagicodesIEExcelOptions _options; - private readonly IExcelExporter _excelExporter; public MagicodesIEExcelExporterProvider(IOptions options) { From e817431fe7e30b035bead5c124b9df539753d57f Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 21 Jun 2025 18:56:09 +0800 Subject: [PATCH 4/7] fix(exporter): fix unit tests --- .../Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs | 5 +++++ .../Exporter/Pdf/LibreOffice/LibreOfficeTestEnvironment.cs | 4 ++++ ...llExcelToPdfProvider.cs => OriginalExcelToPdfProvider.cs} | 5 ++--- 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeTestEnvironment.cs rename aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/{NullExcelToPdfProvider.cs => OriginalExcelToPdfProvider.cs} (60%) diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs index d686cbc12..48dd21670 100644 --- a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs @@ -8,6 +8,11 @@ public class AbpExporterPdfLibreOfficeModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { + // 解决单元测试问题 + if (context.Services.IsAdded()) + { + return; + } if (!LibreOfficeCommands.IsLibreOffliceInstalled()) { throw new Volo.Abp.AbpInitializationException("Libreoffice not installed in the current operation environment of the host, please refer to the document after installation using ` AbpExporterPdfLibreOfficeModule ` module."); diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeTestEnvironment.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeTestEnvironment.cs new file mode 100644 index 000000000..09323204d --- /dev/null +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeTestEnvironment.cs @@ -0,0 +1,4 @@ +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; +public class LibreOfficeTestEnvironment +{ +} diff --git a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/NullExcelToPdfProvider.cs b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/OriginalExcelToPdfProvider.cs similarity index 60% rename from aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/NullExcelToPdfProvider.cs rename to aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/OriginalExcelToPdfProvider.cs index 293adf18e..8cccfcf34 100644 --- a/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/NullExcelToPdfProvider.cs +++ b/aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/OriginalExcelToPdfProvider.cs @@ -6,11 +6,10 @@ using Volo.Abp.DependencyInjection; namespace LINGYUN.Abp.Exporter.Pdf; [Dependency(TryRegister = true)] -public class NullExcelToPdfProvider : IExcelToPdfProvider, ISingletonDependency +public class OriginalExcelToPdfProvider : IExcelToPdfProvider, ISingletonDependency { - private readonly static Stream _nullStreamCache = Stream.Null; public virtual Task ParseAsync(Stream excelStream, CancellationToken cancellationToken = default) { - return Task.FromResult(_nullStreamCache); + return Task.FromResult(excelStream); } } From d18588c2bb3c8396acc7f231debfefbfe7706655 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 21 Jun 2025 18:57:22 +0800 Subject: [PATCH 5/7] test(exporter): Add unit tests - Add LibreOffice unit tests - Add Spire.XLS unit tests --- ....Abp.Exporter.Pdf.LibreOffice.Tests.csproj | 20 +++++++++++ ...YUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln | 24 +++++++++++++ .../AbpExporterPdfLibreOfficeTestBase.cs | 6 ++++ .../AbpExporterPdfLibreOfficeTestsModule.cs | 20 +++++++++++ .../AbpExporterPdfLibreOffice_Tests.cs | 5 +++ ...YUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj | 20 +++++++++++ .../AbpExporterPdfSpireLibTestBase.cs | 6 ++++ .../AbpExporterPdfSpireLibTestsModule.cs | 12 +++++++ .../AbpExporterSpireLibOffice_Tests.cs | 5 +++ .../LINGYUN.Abp.Exporter.Pdf.Tests.csproj | 25 +++++++++++++ .../Exporter/Pdf/AbpExporterPdfTestBase.cs | 8 +++++ .../Exporter/Pdf/AbpExporterPdfTestsModule.cs | 20 +++++++++++ .../Exporter/Pdf/ExcelToPdfProvider_Tests.cs | 34 ++++++++++++++++++ .../Abp/Exporter/Pdf/Resources/test.xlsx | Bin 0 -> 8799 bytes 14 files changed, 205 insertions(+) create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj new file mode 100644 index 000000000..ae6eda819 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj @@ -0,0 +1,20 @@ + + + + net9.0 + + false + Debug;Release + AnyCPU + + + + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln new file mode 100644 index 000000000..3efe62149 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests", "LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj", "{F760B606-3243-2655-8219-F8799FFAE4AF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F760B606-3243-2655-8219-F8799FFAE4AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F760B606-3243-2655-8219-F8799FFAE4AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F760B606-3243-2655-8219-F8799FFAE4AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F760B606-3243-2655-8219-F8799FFAE4AF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E1CB4316-1F23-4B1A-B67C-322A416FD6F5} + EndGlobalSection +EndGlobal diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs new file mode 100644 index 000000000..652982b63 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs @@ -0,0 +1,6 @@ +using LINGYUN.Abp.Tests; + +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; +public abstract class AbpExporterPdfLibreOfficeTestBase : AbpTestsBase +{ +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs new file mode 100644 index 000000000..ea288dfe0 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; + +[DependsOn( + typeof(AbpExporterPdfLibreOfficeModule), + typeof(AbpExporterPdfTestsModule), + typeof(AbpAutofacModule))] +public class AbpExporterPdfLibreOfficeTestsModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + if (!LibreOfficeCommands.IsLibreOffliceInstalled()) + { + context.Services.AddSingleton(); + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs new file mode 100644 index 000000000..0112e9d65 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs @@ -0,0 +1,5 @@ +namespace LINGYUN.Abp.Exporter.Pdf.LibreOffice; +public class AbpExporterPdfLibreOffice_Tests : ExcelToPdfProvider_Tests +{ + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj new file mode 100644 index 000000000..689bb3861 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj @@ -0,0 +1,20 @@ + + + + net9.0 + + false + Debug;Release + AnyCPU + + + + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs new file mode 100644 index 000000000..2dddc4d1a --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs @@ -0,0 +1,6 @@ +using LINGYUN.Abp.Tests; + +namespace LINGYUN.Abp.Exporter.Pdf.SpireLib; +public abstract class AbpExporterPdfSpireLibTestBase : AbpTestsBase +{ +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs new file mode 100644 index 000000000..c474d59e1 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Exporter.Pdf.SpireLib; + +[DependsOn( + typeof(AbpExporterPdfSpireLibModule), + typeof(AbpExporterPdfTestsModule), + typeof(AbpAutofacModule))] +public class AbpExporterPdfSpireLibTestsModule : AbpModule +{ +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs new file mode 100644 index 000000000..ea5b95912 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs @@ -0,0 +1,5 @@ +namespace LINGYUN.Abp.Exporter.Pdf.SpireLib; +public class AbpExporterSpireLibOffice_Tests : ExcelToPdfProvider_Tests +{ + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj new file mode 100644 index 000000000..20265586e --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj @@ -0,0 +1,25 @@ + + + + net9.0 + true + false + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs new file mode 100644 index 000000000..106f6c55b --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Modularity; +using Volo.Abp.Testing; + +namespace LINGYUN.Abp.Exporter.Pdf; +public abstract class AbpExporterPdfTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule +{ +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs new file mode 100644 index 000000000..15e901cb9 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs @@ -0,0 +1,20 @@ +using LINGYUN.Abp.Tests; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.Exporter.Pdf; + +[DependsOn( + typeof(AbpVirtualFileSystemModule), + typeof(AbpExporterPdfModule), + typeof(AbpTestsBaseModule))] +public class AbpExporterPdfTestsModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs new file mode 100644 index 000000000..725da41f3 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs @@ -0,0 +1,34 @@ +using Shouldly; +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.IO; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; +using Xunit; + +namespace LINGYUN.Abp.Exporter.Pdf; +public abstract class ExcelToPdfProvider_Tests : AbpExporterPdfTestBase + where TStartupModule : IAbpModule +{ + private readonly IExcelToPdfProvider _excelToPdfProvider; + private readonly IVirtualFileProvider _virtualFileProvider; + public ExcelToPdfProvider_Tests() + { + _excelToPdfProvider = GetRequiredService(); + _virtualFileProvider = GetRequiredService(); + } + + [Fact] + public async virtual Task Should_Parsed() + { + var excelFileInfo = _virtualFileProvider.GetFileInfo("/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx"); + using (var excelStream = excelFileInfo.CreateReadStream()) + { + using (var pdfStream = await _excelToPdfProvider.ParseAsync(excelStream)) + { + pdfStream.Seek(0, System.IO.SeekOrigin.Begin); + pdfStream.Length.ShouldBePositive(); + } + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx b/aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..029db08db2269cfeb30451ae516e8f05b1103be9 GIT binary patch literal 8799 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 s1d#&(|M1pd;eXGGe}!LB{ssPfhSX9+g6%E Date: Sat, 21 Jun 2025 18:58:17 +0800 Subject: [PATCH 6/7] chore(exporter): Add `Spire.XLS` PackageVersion --- Directory.Packages.props | 1 + 1 file changed, 1 insertion(+) diff --git a/Directory.Packages.props b/Directory.Packages.props index d38fbca96..488416c11 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -320,6 +320,7 @@ + From 604437fd0de8f1b431eabbfded5a03cc7a623f7b Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 21 Jun 2025 18:59:15 +0800 Subject: [PATCH 7/7] chore(sln): The solution adds a PDF export module --- aspnet-core/LINGYUN.MicroService.All.sln | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index 6deeeb0ae..708d441b2 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -843,6 +843,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Account.Web.OAu EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Account.OAuth", "modules\account\LINGYUN.Abp.Account.OAuth\LINGYUN.Abp.Account.OAuth.csproj", "{001D0817-1EED-4C04-821E-F815F148EC90}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Exporter.Pdf", "framework\exporter\LINGYUN.Abp.Exporter.Pdf\LINGYUN.Abp.Exporter.Pdf.csproj", "{546E4417-5409-40F4-A125-E08329DD82BB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Exporter.Pdf.LibreOffice", "framework\exporter\LINGYUN.Abp.Exporter.Pdf.LibreOffice\LINGYUN.Abp.Exporter.Pdf.LibreOffice.csproj", "{738A72FB-ED83-4127-AA3B-59BF90635F8F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Exporter.Pdf.SpireLib", "framework\exporter\LINGYUN.Abp.Exporter.Pdf.SpireLib\LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj", "{9950639D-AA4C-4FF1-A65E-9790EB561C8A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2185,6 +2191,18 @@ Global {001D0817-1EED-4C04-821E-F815F148EC90}.Debug|Any CPU.Build.0 = Debug|Any CPU {001D0817-1EED-4C04-821E-F815F148EC90}.Release|Any CPU.ActiveCfg = Release|Any CPU {001D0817-1EED-4C04-821E-F815F148EC90}.Release|Any CPU.Build.0 = Release|Any CPU + {546E4417-5409-40F4-A125-E08329DD82BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {546E4417-5409-40F4-A125-E08329DD82BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {546E4417-5409-40F4-A125-E08329DD82BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {546E4417-5409-40F4-A125-E08329DD82BB}.Release|Any CPU.Build.0 = Release|Any CPU + {738A72FB-ED83-4127-AA3B-59BF90635F8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {738A72FB-ED83-4127-AA3B-59BF90635F8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {738A72FB-ED83-4127-AA3B-59BF90635F8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {738A72FB-ED83-4127-AA3B-59BF90635F8F}.Release|Any CPU.Build.0 = Release|Any CPU + {9950639D-AA4C-4FF1-A65E-9790EB561C8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9950639D-AA4C-4FF1-A65E-9790EB561C8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9950639D-AA4C-4FF1-A65E-9790EB561C8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9950639D-AA4C-4FF1-A65E-9790EB561C8A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2594,6 +2612,9 @@ Global {4105FC8B-E8C6-DBD7-FFEA-EA5AB09C7D08} = {F4923692-D343-4318-AECA-96F580B1A563} {DD11D070-F39E-1C41-1843-AE3ADBE501EF} = {9E72FEB9-A626-4312-892B-CDD043879758} {001D0817-1EED-4C04-821E-F815F148EC90} = {9E72FEB9-A626-4312-892B-CDD043879758} + {546E4417-5409-40F4-A125-E08329DD82BB} = {A4633711-7FB6-411A-8D08-BB9A0A778046} + {738A72FB-ED83-4127-AA3B-59BF90635F8F} = {A4633711-7FB6-411A-8D08-BB9A0A778046} + {9950639D-AA4C-4FF1-A65E-9790EB561C8A} = {A4633711-7FB6-411A-8D08-BB9A0A778046} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}