Skip to content

Commit 1e3cea2

Browse files
committed
(#70) Export Html, Pdf Files
1 parent 20fc109 commit 1e3cea2

File tree

53 files changed

+863
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+863
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
/src/Microservices/Services.Storage/ClassifiedAds.Services.Storage.Api/Migrations/
1313
/src/UIs/reactjs/.eslintcache
1414
.tye/
15+
.local-chromium/
1516

1617
## Ignore Visual Studio temporary files, build results, and
1718
## files generated by popular Visual Studio add-ons.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Threading.Tasks;
2+
3+
namespace ClassifiedAds.CrossCuttingConcerns.HtmlGenerator
4+
{
5+
public interface IHtmlGenerator
6+
{
7+
Task<string> GenerateAsync(string template, object model);
8+
}
9+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.IO;
2+
using System.Threading.Tasks;
3+
4+
namespace ClassifiedAds.CrossCuttingConcerns.PdfConverter
5+
{
6+
public interface IPdfConverter
7+
{
8+
Stream Convert(string html, PdfOptions pdfOptions = null);
9+
10+
Task<Stream> ConvertAsync(string html, PdfOptions pdfOptions = null);
11+
}
12+
13+
public class PdfOptions
14+
{
15+
16+
}
17+
}

src/Microservices/Common/ClassifiedAds.Infrastructure/ClassifiedAds.Infrastructure.csproj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<PackageReference Include="Confluent.Kafka" Version="1.5.2" />
3131
<PackageReference Include="CryptographyHelper" Version="1.0.0-beta4" />
3232
<PackageReference Include="Dapper.StrongName" Version="2.0.35" />
33+
<PackageReference Include="DinkToPdf" Version="1.0.8" />
3334
<PackageReference Include="Google.Protobuf" Version="3.10.0" />
3435
<PackageReference Include="Grpc.Net.Client" Version="2.25.0" />
3536
<PackageReference Include="IdentityModel" Version="4.4.0" />
@@ -60,7 +61,9 @@
6061
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.0.0-rc1.1" />
6162
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.0.0-rc1.1" />
6263
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.0.0-rc1.1" />
64+
<PackageReference Include="PuppeteerSharp" Version="4.0.0" />
6365
<PackageReference Include="RabbitMQ.Client" Version="6.2.1" />
66+
<PackageReference Include="RazorLight" Version="2.0.0-rc.3" />
6467
<PackageReference Include="SendGrid" Version="9.21.2" />
6568
<PackageReference Include="Serilog" Version="2.10.0" />
6669
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
@@ -79,4 +82,15 @@
7982
<ProjectReference Include="..\ClassifiedAds.Domain\ClassifiedAds.Domain.csproj" />
8083
</ItemGroup>
8184

85+
<ItemGroup>
86+
<ContentWithTargetPath Include="..\libs\libwkhtmltox\libwkhtmltox-0.12.4-x64.dll">
87+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
88+
<TargetPath>libwkhtmltox.dll</TargetPath>
89+
</ContentWithTargetPath>
90+
<ContentWithTargetPath Include="..\libs\libwkhtmltox\libwkhtmltox-0.12.4-x64.so">
91+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
92+
<TargetPath>libwkhtmltox.so</TargetPath>
93+
</ContentWithTargetPath>
94+
</ItemGroup>
95+
8296
</Project>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using ClassifiedAds.CrossCuttingConcerns.HtmlGenerator;
2+
using RazorLight;
3+
using System.Threading.Tasks;
4+
5+
namespace ClassifiedAds.Infrastructure.HtmlGenerators
6+
{
7+
public class HtmlGenerator : IHtmlGenerator
8+
{
9+
private readonly IRazorLightEngine _razorLightEngine;
10+
11+
public HtmlGenerator(IRazorLightEngine razorLightEngine)
12+
{
13+
_razorLightEngine = razorLightEngine;
14+
}
15+
16+
public Task<string> GenerateAsync(string template, object model)
17+
{
18+
return _razorLightEngine.CompileRenderAsync(template, model);
19+
}
20+
}
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using ClassifiedAds.CrossCuttingConcerns.HtmlGenerator;
2+
using ClassifiedAds.Infrastructure.HtmlGenerators;
3+
using RazorLight;
4+
using System;
5+
6+
namespace Microsoft.Extensions.DependencyInjection
7+
{
8+
public static class HtmlGeneratorCollectionExtensions
9+
{
10+
public static IServiceCollection AddHtmlGenerator(this IServiceCollection services)
11+
{
12+
var engine = new RazorLightEngineBuilder()
13+
.UseFileSystemProject(Environment.CurrentDirectory)
14+
.UseMemoryCachingProvider()
15+
.Build();
16+
17+
services.AddSingleton<IRazorLightEngine>(engine);
18+
services.AddSingleton<IHtmlGenerator, HtmlGenerator>();
19+
20+
return services;
21+
}
22+
}
23+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using ClassifiedAds.CrossCuttingConcerns.PdfConverter;
2+
using DinkToPdf;
3+
using DinkToPdf.Contracts;
4+
using System.IO;
5+
using System.Threading.Tasks;
6+
7+
namespace ClassifiedAds.Infrastructure.PdfConverters.DinkToPdf
8+
{
9+
public class DinkToPdfConverter : IPdfConverter
10+
{
11+
private readonly IConverter _converter;
12+
13+
public DinkToPdfConverter(IConverter converter)
14+
{
15+
_converter = converter;
16+
}
17+
18+
public Stream Convert(string html, PdfOptions pdfOptions = null)
19+
{
20+
var doc = new HtmlToPdfDocument()
21+
{
22+
GlobalSettings =
23+
{
24+
ColorMode = ColorMode.Color,
25+
Orientation = Orientation.Portrait,
26+
PaperSize = PaperKind.A4,
27+
Margins = new MarginSettings() { Top = 10, Bottom = 15, Left = 10, Right = 10 },
28+
},
29+
Objects =
30+
{
31+
new ObjectSettings()
32+
{
33+
PagesCount = true,
34+
HtmlContent = html,
35+
WebSettings = { DefaultEncoding = "utf-8", Background = true },
36+
HeaderSettings = { FontSize = 9, Right = "Page [page] of [toPage]", Line = true, Spacing = 2.812 },
37+
},
38+
},
39+
};
40+
41+
byte[] pdf = _converter.Convert(doc);
42+
43+
return new MemoryStream(pdf);
44+
}
45+
46+
public Task<Stream> ConvertAsync(string html, PdfOptions pdfOptions = null)
47+
{
48+
return Task.FromResult(Convert(html, pdfOptions));
49+
}
50+
}
51+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using ClassifiedAds.CrossCuttingConcerns.PdfConverter;
2+
using ClassifiedAds.Infrastructure.PdfConverters.DinkToPdf;
3+
using DinkToPdf;
4+
using DinkToPdf.Contracts;
5+
6+
namespace Microsoft.Extensions.DependencyInjection
7+
{
8+
public static class DinkToPdfConverterCollectionExtensions
9+
{
10+
public static IServiceCollection AddDinkToPdfConverter(this IServiceCollection services)
11+
{
12+
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
13+
services.AddSingleton<IPdfConverter, DinkToPdfConverter>();
14+
15+
return services;
16+
}
17+
}
18+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using ClassifiedAds.CrossCuttingConcerns.PdfConverter;
2+
using PuppeteerSharp;
3+
using System.IO;
4+
using System.Threading.Tasks;
5+
6+
namespace ClassifiedAds.Infrastructure.PdfConverters.PuppeteerSharp
7+
{
8+
public class PuppeteerSharpConverter : IPdfConverter
9+
{
10+
public Stream Convert(string html, CrossCuttingConcerns.PdfConverter.PdfOptions pdfOptions = null)
11+
{
12+
return ConvertAsync(html, pdfOptions).GetAwaiter().GetResult();
13+
}
14+
15+
public async Task<Stream> ConvertAsync(string html, CrossCuttingConcerns.PdfConverter.PdfOptions pdfOptions = null)
16+
{
17+
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
18+
await using var page = await browser.NewPageAsync();
19+
await page.SetContentAsync(html);
20+
return new MemoryStream(await page.PdfDataAsync(new global::PuppeteerSharp.PdfOptions
21+
{
22+
PrintBackground = true,
23+
}));
24+
}
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using ClassifiedAds.CrossCuttingConcerns.PdfConverter;
2+
using ClassifiedAds.Infrastructure.PdfConverters.PuppeteerSharp;
3+
using PuppeteerSharp;
4+
5+
namespace Microsoft.Extensions.DependencyInjection
6+
{
7+
public static class PuppeteerSharpConverterCollectionExtensions
8+
{
9+
public static IServiceCollection AddPuppeteerSharpPdfConverter(this IServiceCollection services)
10+
{
11+
var browserFetcher = new BrowserFetcher();
12+
browserFetcher.DownloadAsync().GetAwaiter().GetResult();
13+
14+
services.AddSingleton<IPdfConverter, PuppeteerSharpConverter>();
15+
16+
return services;
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)