Browse Source

Merge pull request #1249 from colinin/pdf-module

feat(exporter): Add a PDF export module
pull/1267/head
yx lin 8 months ago
committed by GitHub
parent
commit
7593e98d1e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      Directory.Packages.props
  2. 21
      aspnet-core/LINGYUN.MicroService.All.sln
  3. 4
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/FodyWeavers.xml
  4. 5
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/LINGYUN.Abp.Exporter.Core.csproj
  5. 4
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.MagicodesIE.Excel/LINGYUN/Abp/Exporter/MagicodesIEExcelExporterProvider.cs
  6. 3
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml
  7. 30
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xsd
  8. 21
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN.Abp.Exporter.Pdf.LibreOffice.csproj
  9. 22
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs
  10. 103
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeCommands.cs
  11. 52
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeExcelToPdfProvider.cs
  12. 4
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/LibreOfficeTestEnvironment.cs
  13. 26
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/README.md
  14. 3
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml
  15. 30
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xsd
  16. 25
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj
  17. 13
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibModule.cs
  18. 20
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN/Abp/Exporter/Pdf/SpireLib/SpireExcelToPdfProvider.cs
  19. 25
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/README.md
  20. 3
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml
  21. 30
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xsd
  22. 21
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN.Abp.Exporter.Pdf.csproj
  23. 8
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfModule.cs
  24. 10
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/IExcelToPdfProvider.cs
  25. 15
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/OriginalExcelToPdfProvider.cs
  26. 38
      aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/README.md
  27. 20
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj
  28. 24
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.sln
  29. 6
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestBase.cs
  30. 20
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeTestsModule.cs
  31. 5
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOffice_Tests.cs
  32. 20
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj
  33. 6
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestBase.cs
  34. 12
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterPdfSpireLibTestsModule.cs
  35. 5
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN/Abp/Exporter/Pdf/SpireLib/AbpExporterSpireLibOffice_Tests.cs
  36. 25
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj
  37. 8
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestBase.cs
  38. 20
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/AbpExporterPdfTestsModule.cs
  39. 34
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/ExcelToPdfProvider_Tests.cs
  40. BIN
      aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx

1
Directory.Packages.props

@ -320,6 +320,7 @@
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.8" />
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="2.1.6" />
<PackageVersion Include="StackExchange.Redis" Version="2.8.31" />
<PackageVersion Include="Spire.XLS" Version="15.5.1" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="8.1.1" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageVersion Include="Tencent.QCloud.Cos.Sdk" Version="5.4.37" />

21
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}

4
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/FodyWeavers.xml

@ -1,3 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

5
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Core/LINGYUN.Abp.Exporter.Core.csproj

@ -15,12 +15,11 @@
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\Exporter\Localization\Resources\zh-Hans.json" />
<None Remove="LINGYUN\Abp\Exporter\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\Exporter\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\Exporter\Localization\Resources\zh-Hans.json" />
<EmbeddedResource Include="LINGYUN\Abp\Exporter\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>

4
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<AbpExporterMagicodesIEExcelOptions> options)
{

3
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

21
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN.Abp.Exporter.Pdf.LibreOffice.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.Exporter.Pdf.LibreOffice</AssemblyName>
<PackageId>LINGYUN.Abp.Exporter.Pdf.LibreOffice</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Pdf\LINGYUN.Abp.Exporter.Pdf.csproj" />
</ItemGroup>
</Project>

22
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.LibreOffice/LINGYUN/Abp/Exporter/Pdf/LibreOffice/AbpExporterPdfLibreOfficeModule.cs

@ -0,0 +1,22 @@
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 (context.Services.IsAdded<LibreOfficeTestEnvironment>())
{
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.");
}
context.Services.AddTransient<IExcelToPdfProvider, LibreOfficeExcelToPdfProvider>();
}
}

103
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());
}
/// <summary>
/// LibreOffice是否可用
/// </summary>
/// <param name="commandFile"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// Excel转换为Pdf
/// </summary>
/// <param name="excelFile"></param>
/// <param name="outputPath"></param>
/// <exception cref="Exception"></exception>
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}");
}
}
}

52
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<Stream> 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);
}
}
}

4
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
{
}

26
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";
}
}
```

3
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

25
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf.SpireLib/LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.Exporter.Pdf.SpireLib</AssemblyName>
<PackageId>LINGYUN.Abp.Exporter.Pdf.SpireLib</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Spire.XLS" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Pdf\LINGYUN.Abp.Exporter.Pdf.csproj" />
</ItemGroup>
</Project>

13
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<IExcelToPdfProvider, SpireExcelToPdfProvider>();
}
}

20
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<Stream> 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);
}
}

25
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");
}
}
```

3
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

21
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN.Abp.Exporter.Pdf.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.Exporter.Pdf</AssemblyName>
<PackageId>LINGYUN.Abp.Exporter.Pdf</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Core" />
</ItemGroup>
</Project>

8
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
{
}

10
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<Stream> ParseAsync(Stream excelStream, CancellationToken cancellationToken = default);
}

15
aspnet-core/framework/exporter/LINGYUN.Abp.Exporter.Pdf/LINGYUN/Abp/Exporter/Pdf/OriginalExcelToPdfProvider.cs

@ -0,0 +1,15 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.Exporter.Pdf;
[Dependency(TryRegister = true)]
public class OriginalExcelToPdfProvider : IExcelToPdfProvider, ISingletonDependency
{
public virtual Task<Stream> ParseAsync(Stream excelStream, CancellationToken cancellationToken = default)
{
return Task.FromResult(excelStream);
}
}

38
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<IRemoteStreamContent> ExportAsync(Stream excelStream)
{
var stream = await _exporterProvider.ParseAsync(excelStream);
return new RemoteStreamContent(stream, "demo.pdf");
}
}
```

20
aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests/LINGYUN.Abp.Exporter.Pdf.LibreOffice.Tests.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
<Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\framework\exporter\LINGYUN.Abp.Exporter.Pdf.LibreOffice\LINGYUN.Abp.Exporter.Pdf.LibreOffice.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Pdf.Tests\LINGYUN.Abp.Exporter.Pdf.Tests.csproj" />
</ItemGroup>
</Project>

24
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

6
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<AbpExporterPdfLibreOfficeTestsModule>
{
}

20
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<LibreOfficeTestEnvironment>();
}
}
}

5
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<AbpExporterPdfLibreOfficeTestsModule>
{
}

20
aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests/LINGYUN.Abp.Exporter.Pdf.SpireLib.Tests.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
<Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\framework\exporter\LINGYUN.Abp.Exporter.Pdf.SpireLib\LINGYUN.Abp.Exporter.Pdf.SpireLib.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Pdf.Tests\LINGYUN.Abp.Exporter.Pdf.Tests.csproj" />
</ItemGroup>
</Project>

6
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<AbpExporterPdfSpireLibTestsModule>
{
}

12
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
{
}

5
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<AbpExporterPdfSpireLibTestsModule>
{
}

25
aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN.Abp.Exporter.Pdf.Tests.csproj

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<IsPackable>false</IsPackable>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\Exporter\Pdf\Resources\test.xlsx" />
<EmbeddedResource Include="LINGYUN\Abp\Exporter\Pdf\Resources\test.xlsx" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\framework\exporter\LINGYUN.Abp.Exporter.Pdf\LINGYUN.Abp.Exporter.Pdf.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" />
</ItemGroup>
</Project>

8
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<TStartupModule> : AbpIntegratedTest<TStartupModule>
where TStartupModule : IAbpModule
{
}

20
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<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpExporterPdfTestsModule>();
});
}
}

34
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<TStartupModule> : AbpExporterPdfTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
private readonly IExcelToPdfProvider _excelToPdfProvider;
private readonly IVirtualFileProvider _virtualFileProvider;
public ExcelToPdfProvider_Tests()
{
_excelToPdfProvider = GetRequiredService<IExcelToPdfProvider>();
_virtualFileProvider = GetRequiredService<IVirtualFileProvider>();
}
[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();
}
}
}
}

BIN
aspnet-core/tests/LINGYUN.Abp.Exporter.Pdf.Tests/LINGYUN/Abp/Exporter/Pdf/Resources/test.xlsx

Binary file not shown.
Loading…
Cancel
Save