From fdcb39746257dbe6ee745d3be847070ec03faeeb Mon Sep 17 00:00:00 2001 From: Arjan Kwakkel Date: Mon, 22 Jul 2024 16:00:25 +0200 Subject: [PATCH 01/12] Support .NET 8, replace deprecated iTextSharp with itext7 and upgrade packages --- .../Rotativa.AspNetCore.DemoApp.csproj | 2 +- Rotativa.AspNetCore.Tests/PDFParser.cs | 9 +++++---- Rotativa.AspNetCore.Tests/PdfTester.cs | 20 ++++++++++++------- .../Rotativa.AspNetCore.Tests.csproj | 16 +++++++-------- Rotativa.AspNetCore.Tests/RotativaTests.cs | 6 ++++-- .../Rotativa.AspNetCore.csproj | 14 ++++++++----- 6 files changed, 40 insertions(+), 27 deletions(-) diff --git a/Rotativa.AspNetCore.DemoApp/Rotativa.AspNetCore.DemoApp.csproj b/Rotativa.AspNetCore.DemoApp/Rotativa.AspNetCore.DemoApp.csproj index 6834c82..5693452 100644 --- a/Rotativa.AspNetCore.DemoApp/Rotativa.AspNetCore.DemoApp.csproj +++ b/Rotativa.AspNetCore.DemoApp/Rotativa.AspNetCore.DemoApp.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable diff --git a/Rotativa.AspNetCore.Tests/PDFParser.cs b/Rotativa.AspNetCore.Tests/PDFParser.cs index 7dbe475..d17f3c8 100644 --- a/Rotativa.AspNetCore.Tests/PDFParser.cs +++ b/Rotativa.AspNetCore.Tests/PDFParser.cs @@ -1,4 +1,4 @@ -using iTextSharp.text.pdf; +using iText.Kernel.Pdf; using System; using System.Collections.Generic; using System.IO; @@ -43,19 +43,20 @@ public bool ExtractText(string inFileName, string outFileName) { // Create a reader for the given PDF file var reader = new PdfReader(inFileName); + var document = new PdfDocument(reader); //outFile = File.CreateText(outFileName); outFile = new StreamWriter(outFileName, false, System.Text.Encoding.UTF8); Console.Write("Processing: "); int totalLen = 68; - float charUnit = ((float)totalLen) / (float)reader.NumberOfPages; + float charUnit = ((float)totalLen) / (float)document.GetNumberOfPages(); int totalWritten = 0; float curUnit = 0; - for (int page = 1; page <= reader.NumberOfPages; page++) + for (int page = 1; page <= document.GetNumberOfPages(); page++) { - outFile.Write(ExtractTextFromPDFBytes(reader.GetPageContent(page)) + " "); + outFile.Write(ExtractTextFromPDFBytes(document.GetPage(page).GetContentBytes()) + " "); // Write the progress. if (charUnit >= 1.0f) diff --git a/Rotativa.AspNetCore.Tests/PdfTester.cs b/Rotativa.AspNetCore.Tests/PdfTester.cs index ce1a96f..3fd59e1 100644 --- a/Rotativa.AspNetCore.Tests/PdfTester.cs +++ b/Rotativa.AspNetCore.Tests/PdfTester.cs @@ -1,6 +1,10 @@ -using iTextSharp.text.exceptions; -using iTextSharp.text.pdf; -using iTextSharp.text.pdf.parser; +//using iTextSharp.text.exceptions; +//using iTextSharp.text.pdf; +//using iTextSharp.text.pdf.parser; +using iText.Kernel.Exceptions; +using iText.Kernel.Pdf; +using iText.Kernel.Pdf.Canvas.Parser; +using iText.Kernel.Pdf.Canvas.Parser.Listener; using System; using System.Collections.Generic; using System.Linq; @@ -22,12 +26,12 @@ public void LoadPdf(byte[] pdfcontent) { try { - this.pdfReader = new PdfReader(pdfcontent); + this.pdfReader = new PdfReader(new MemoryStream(pdfcontent)); var parser = new PDFParser(); var parsed = parser.ExtractTextFromPDFBytes(pdfcontent); this.PdfIsValid = true; } - catch (InvalidPdfException ex) + catch (PdfException ex) { this.PdfException = ex; this.PdfIsValid = false; @@ -36,10 +40,12 @@ public void LoadPdf(byte[] pdfcontent) public bool PdfContains(string text) { - for (int page = 1; page <= pdfReader.NumberOfPages; page++) + var pdfDocument = new PdfDocument(this.pdfReader); + + for (int page = 1; page <= pdfDocument.GetNumberOfPages(); page++) { var strategy = new SimpleTextExtractionStrategy(); - string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy); + string currentText = PdfTextExtractor.GetTextFromPage(pdfDocument.GetPage(page), strategy); currentText = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText))); if (currentText.Contains(text)) diff --git a/Rotativa.AspNetCore.Tests/Rotativa.AspNetCore.Tests.csproj b/Rotativa.AspNetCore.Tests/Rotativa.AspNetCore.Tests.csproj index 2c35671..f67cec9 100644 --- a/Rotativa.AspNetCore.Tests/Rotativa.AspNetCore.Tests.csproj +++ b/Rotativa.AspNetCore.Tests/Rotativa.AspNetCore.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 enable enable @@ -10,15 +10,15 @@ - - - - - + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/Rotativa.AspNetCore.Tests/RotativaTests.cs b/Rotativa.AspNetCore.Tests/RotativaTests.cs index 76d53fb..e500e87 100644 --- a/Rotativa.AspNetCore.Tests/RotativaTests.cs +++ b/Rotativa.AspNetCore.Tests/RotativaTests.cs @@ -36,7 +36,8 @@ public void Dispose() [Theory(DisplayName = "should return the demo home page")] //[InlineData("http://localhost:64310", "Asp.net core 2.0")] //[InlineData("https://localhost:44375", "Asp.net core 3.1")] - [InlineData("https://localhost:7059", "Asp.net 6")] + //[InlineData("https://localhost:7059", "Asp.net 6")] + [InlineData("https://localhost:56246", "Asp.net 8")] public void Is_the_site_reachable(string url, string site) { selenium.Navigate().GoToUrl(url); @@ -46,7 +47,8 @@ public void Is_the_site_reachable(string url, string site) [Theory(DisplayName = "can get the PDF from the contact link")] //[InlineData("http://localhost:64310", "Asp.net core 2.0")] //[InlineData("https://localhost:44375", "Asp.net core 3.1")] - [InlineData("https://localhost:7059", "Asp.net 6")] + //[InlineData("https://localhost:7059", "Asp.net 6")] + [InlineData("https://localhost:56246", "Asp.net 8")] public void Contact_PDF(string url, string site) { selenium.Navigate().GoToUrl(url); diff --git a/Rotativa.AspNetCore/Rotativa.AspNetCore.csproj b/Rotativa.AspNetCore/Rotativa.AspNetCore.csproj index f38b4f3..f93d667 100644 --- a/Rotativa.AspNetCore/Rotativa.AspNetCore.csproj +++ b/Rotativa.AspNetCore/Rotativa.AspNetCore.csproj @@ -1,18 +1,18 @@  - netstandard2.0;netcoreapp3.1;net6;net5.0;net7 + netstandard2.0;netcoreapp3.1;net6;net5.0;net7;net8 true - 1.3.2 + 1.3.3 true https://github.com/webgio/Rotativa.AspNetCore https://github.com/webgio/Rotativa.AspNetCore Viva Software di Bozio Giorgio Giorgio Bozio - Rotativa: PDF easy creation for Asp.Net 6 and Asp.Net Core - Multi target enabling .net core 3.1, .net 5, .net 6, .net 7 + Rotativa: PDF easy creation for Asp.Net 6, Asp.Net 8 and Asp.Net Core + Multi target enabling .net core 3.1, .net 5, .net 6, .net 7, .net 8 PDF AspNetCore - 2023 Viva Software di Bozio Giorgio + 2024 Viva Software di Bozio Giorgio MIT README.md @@ -30,6 +30,10 @@ + + + + From 7db7f859e1471062fb492cb8be44cd3a9938686e Mon Sep 17 00:00:00 2001 From: Arjan Kwakkel Date: Tue, 23 Jul 2024 17:31:09 +0200 Subject: [PATCH 02/12] Add zoom flag option for Pdfs. --- Rotativa.AspNetCore/AsPdfResultBase.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Rotativa.AspNetCore/AsPdfResultBase.cs b/Rotativa.AspNetCore/AsPdfResultBase.cs index 4c6d3a1..0aaa415 100644 --- a/Rotativa.AspNetCore/AsPdfResultBase.cs +++ b/Rotativa.AspNetCore/AsPdfResultBase.cs @@ -37,6 +37,12 @@ protected AsPdfResultBase() [OptionFlag("-O")] public Orientation? PageOrientation { get; set; } + /// + /// Sets the page zoom. + /// + [OptionFlag("--zoom")] + public double? Zoom { get; set; } + /// /// Sets the page margins. /// From 1a1dee82e367a32f3bb743b87ba2ee52b89b7a01 Mon Sep 17 00:00:00 2001 From: Arjan Kwakkel Date: Tue, 23 Jul 2024 17:32:37 +0200 Subject: [PATCH 03/12] Fix obsolete message with correct property name. --- Rotativa.AspNetCore/AsPdfResultBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rotativa.AspNetCore/AsPdfResultBase.cs b/Rotativa.AspNetCore/AsPdfResultBase.cs index 0aaa415..5d9903f 100644 --- a/Rotativa.AspNetCore/AsPdfResultBase.cs +++ b/Rotativa.AspNetCore/AsPdfResultBase.cs @@ -61,7 +61,7 @@ protected override string GetContentType() /// /// Path to wkhtmltopdf binary. /// - [Obsolete("Use WkhtmlPath instead of CookieName.", false)] + [Obsolete("Use WkhtmlPath instead of WkhtmltopdfPath.", false)] public string WkhtmltopdfPath { get From 7a2cad672ed3666a35941cb0564f7c83899d0afa Mon Sep 17 00:00:00 2001 From: Arjan Kwakkel Date: Tue, 23 Jul 2024 17:34:24 +0200 Subject: [PATCH 04/12] Allow the demo project to build. --- Rotativa.AspNetCore.sln | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Rotativa.AspNetCore.sln b/Rotativa.AspNetCore.sln index ff13c7d..e0415e8 100644 --- a/Rotativa.AspNetCore.sln +++ b/Rotativa.AspNetCore.sln @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rotativa.AspNetCore.DemoCor EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rotativa.AspNetCore.Demo", "Rotativa.AspNetCore.Demo\Rotativa.AspNetCore.Demo.csproj", "{AC72409F-AAC8-496F-920A-06D92755AC38}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rotativa.AspNetCore.Tests", "Rotativa.AspNetCore.Tests\Rotativa.AspNetCore.Tests.csproj", "{DD6DAABC-D9A0-4744-8FF9-5318EF756524}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rotativa.AspNetCore.Tests", "Rotativa.AspNetCore.Tests\Rotativa.AspNetCore.Tests.csproj", "{DD6DAABC-D9A0-4744-8FF9-5318EF756524}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -24,6 +24,7 @@ Global {D9D23B29-06C7-4130-84B5-100E9E3DA048}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9D23B29-06C7-4130-84B5-100E9E3DA048}.Release|Any CPU.Build.0 = Release|Any CPU {9E33D9A0-2F7B-467B-8B58-D62D44C9E0E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E33D9A0-2F7B-467B-8B58-D62D44C9E0E7}.Debug|Any CPU.Build.0 = Debug|Any CPU {9E33D9A0-2F7B-467B-8B58-D62D44C9E0E7}.Release|Any CPU.ActiveCfg = Release|Any CPU {9E33D9A0-2F7B-467B-8B58-D62D44C9E0E7}.Release|Any CPU.Build.0 = Release|Any CPU {68798C66-D7C2-46B1-A232-0CFC7BEDD72E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU From 505f65502ff37a41a647c53f6d1b5abf8c59a4f2 Mon Sep 17 00:00:00 2001 From: Arjan Kwakkel Date: Wed, 24 Jul 2024 00:22:27 +0200 Subject: [PATCH 05/12] Add ViewAsImage support, expand DemoApp with image examples and create a new package version --- .../Controllers/HomeController.cs | 22 +++ .../Views/Home/ContactDemo.cshtml | 17 +++ .../Views/Home/PrivacyImage.cshtml | 6 + .../Views/Shared/_Layout.cshtml | 10 +- Rotativa.AspNetCore/AsImageResultBase.cs | 73 ++++++++++ Rotativa.AspNetCore/AsPdfResultBase.cs | 1 + Rotativa.AspNetCore/AsResultBase.cs | 79 ++++++++++- Rotativa.AspNetCore/README.md | 4 +- .../Rotativa.AspNetCore.csproj | 6 +- Rotativa.AspNetCore/ViewAsImage.cs | 75 ++++++++++ Rotativa.AspNetCore/ViewAsPdf.cs | 134 +++--------------- Rotativa.AspNetCore/WkhtmltoimageDriver.cs | 37 +++++ 12 files changed, 339 insertions(+), 125 deletions(-) create mode 100644 Rotativa.AspNetCore.DemoApp/Views/Home/ContactDemo.cshtml create mode 100644 Rotativa.AspNetCore.DemoApp/Views/Home/PrivacyImage.cshtml create mode 100644 Rotativa.AspNetCore/AsImageResultBase.cs create mode 100644 Rotativa.AspNetCore/ViewAsImage.cs create mode 100644 Rotativa.AspNetCore/WkhtmltoimageDriver.cs diff --git a/Rotativa.AspNetCore.DemoApp/Controllers/HomeController.cs b/Rotativa.AspNetCore.DemoApp/Controllers/HomeController.cs index 9c16a0f..b710990 100644 --- a/Rotativa.AspNetCore.DemoApp/Controllers/HomeController.cs +++ b/Rotativa.AspNetCore.DemoApp/Controllers/HomeController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Rotativa.AspNetCore.DemoApp.Models; using System.Diagnostics; +using Rotativa.AspNetCore.Options; namespace Rotativa.AspNetCore.DemoApp.Controllers { @@ -29,6 +30,27 @@ public IActionResult Privacy() return new ViewAsPdf(); } + public IActionResult ContactImage() + { + ViewData["Message"] = "Your contact page image."; + + // Example on how to set custom data. + // For demo purposes we changed the name of the view, and specified that it isn't a partial view. + // IsPartialView is false by default. We add some additional ViewData. + // Using custom options 'Format' and 'Quality' as a demo. + // See AsImageResultBase for more options. + return new ViewAsImage("ContactDemo", isPartialView: false, viewData: ViewData) + { + Format = ImageFormat.png, + Quality = 90 + }; + } + + public IActionResult PrivacyImage() + { + return new ViewAsImage(); + } + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { diff --git a/Rotativa.AspNetCore.DemoApp/Views/Home/ContactDemo.cshtml b/Rotativa.AspNetCore.DemoApp/Views/Home/ContactDemo.cshtml new file mode 100644 index 0000000..b932f6d --- /dev/null +++ b/Rotativa.AspNetCore.DemoApp/Views/Home/ContactDemo.cshtml @@ -0,0 +1,17 @@ +@{ + ViewData["Title"] = "Contact"; +} +

@ViewData["Title"]

+

@ViewData["Message"]

+ +
+ One Microsoft Way
+ Redmond, WA 98052-6399
+ P: + 425.555.0100 +
+ +
+ Support: Support@example.com
+ Marketing: Marketing@example.com +
diff --git a/Rotativa.AspNetCore.DemoApp/Views/Home/PrivacyImage.cshtml b/Rotativa.AspNetCore.DemoApp/Views/Home/PrivacyImage.cshtml new file mode 100644 index 0000000..af4fb19 --- /dev/null +++ b/Rotativa.AspNetCore.DemoApp/Views/Home/PrivacyImage.cshtml @@ -0,0 +1,6 @@ +@{ + ViewData["Title"] = "Privacy Policy"; +} +

@ViewData["Title"]

+ +

Use this page to detail your site's privacy policy.

diff --git a/Rotativa.AspNetCore.DemoApp/Views/Shared/_Layout.cshtml b/Rotativa.AspNetCore.DemoApp/Views/Shared/_Layout.cshtml index ab09ea3..d1937c0 100644 --- a/Rotativa.AspNetCore.DemoApp/Views/Shared/_Layout.cshtml +++ b/Rotativa.AspNetCore.DemoApp/Views/Shared/_Layout.cshtml @@ -3,7 +3,7 @@ - @ViewData["Title"] - Rotativa.AspNetCore.Demo + @ViewData["Title"] - Rotativa.AspNetCore.Demo v @@ -12,7 +12,7 @@