From ef04a4e5d50bdeed243caf6aa323c118a3988309 Mon Sep 17 00:00:00 2001 From: Mo Ibrahim Date: Mon, 2 Dec 2024 18:11:54 +0200 Subject: [PATCH 1/2] Fix: Apply 100 percentage widths to tables and percentage widths cells when converting HTML to Word --- HtmlToOpenXml.sln | 58 ++++---- examples/Demo/Program.cs | 2 +- examples/Demo/Resources/CompleteRunTest.html | 134 +++++++++++------- .../Expressions/Table/TableCellExpression.cs | 27 +++- .../Expressions/Table/TableExpression.cs | 18 +-- 5 files changed, 141 insertions(+), 98 deletions(-) diff --git a/HtmlToOpenXml.sln b/HtmlToOpenXml.sln index d702ded..2a20d0c 100644 --- a/HtmlToOpenXml.sln +++ b/HtmlToOpenXml.sln @@ -14,33 +14,33 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlToOpenXml.Tests", "test\HtmlToOpenXml.Tests\HtmlToOpenXml.Tests.csproj", "{CA0A68E0-45A0-4A01-A061-F951D93D6906}" EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.Build.0 = Release|Any CPU - {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.Build.0 = Release|Any CPU - {CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {EF700F30-C9BB-49A6-912C-E3B77857B514} = {58520A98-BA53-4BA4-AAE3-786AA21331D6} - {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A} - {CA0A68E0-45A0-4A01-A061-F951D93D6906} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {14EE1026-6507-4295-9FEE-67A55C3849CE} - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.Build.0 = Release|Any CPU + {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.Build.0 = Release|Any CPU + {CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {EF700F30-C9BB-49A6-912C-E3B77857B514} = {58520A98-BA53-4BA4-AAE3-786AA21331D6} + {A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A} + {CA0A68E0-45A0-4A01-A061-F951D93D6906} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {14EE1026-6507-4295-9FEE-67A55C3849CE} + EndGlobalSection EndGlobal diff --git a/examples/Demo/Program.cs b/examples/Demo/Program.cs index 0620d54..e794af4 100644 --- a/examples/Demo/Program.cs +++ b/examples/Demo/Program.cs @@ -74,4 +74,4 @@ static void AssertThatOpenXmlDocumentIsValid(WordprocessingDocument wpDoc) Console.ReadLine(); } } -} \ No newline at end of file +} diff --git a/examples/Demo/Resources/CompleteRunTest.html b/examples/Demo/Resources/CompleteRunTest.html index 0976ee1..9c98726 100644 --- a/examples/Demo/Resources/CompleteRunTest.html +++ b/examples/Demo/Resources/CompleteRunTest.html @@ -4,6 +4,25 @@ + + + + + + + + + + + + + + + + + +
Column 1Column 2Column 3
Row 1, Cell 1Row 1, Cell 2Row 1, Cell 3
Row 2, Cell 1Row 2, Cell 2Row 2, Cell 3
+

Heading 1

Heading 2

@@ -15,8 +34,11 @@
Heading 5
Small caps
Strike Line Through Overline Underline
Bold
- This is a bold - text + + This is a + bold + text + Bold
Bolder
Lighter
@@ -47,7 +69,8 @@
Heading 5
Red dot -

Heading 5 OfDEXhz/AIRbxtAkV1pYNrJHNC0qSbPlDKQDg8e3tVD4Q6BKPGmp67Y2lxbaJ5ckVo04IMgZ 1KjnqAByfXFezMiv95Q2PUZoCKOigY9BSkA9QDjmgqGBDAEHsaia0tnQxtbxMjdVKAg0W9pb Wilba3ihB6iNAufyoltLaZw8tvFIw6FkBNSgADA4FLRRRRRRRX//2Q== - ">

+ "> +

Smiley face @@ -102,79 +126,81 @@
Heading 5

-
-For 50 years, WWF has been protecting the future of nature. The world's leading conservation organization, WWF works in 100 countries and is supported by 1.2 million members in the United States and close to 5 million globally. -
+
+ For 50 years, WWF has been protecting the future of nature. The world's leading conservation organization, WWF works in 100 countries and is supported by 1.2 million members in the United States and close to 5 million globally. +
-
My Text +
My Text -

An ordered list:

+

An ordered list:

    -
  1. Coffee
  2. -
  3. Tea
  4. -
  5. Milk -
      -
    • Coffee
    • -
    • Tea -
        -
      1. Earl Grey
      2. -
      3. Green
      4. -
      5. Rosboh
      6. -
      -
    • -
    • Milk
    • -
    -
  6. -
  7. Wine
  8. +
  9. Coffee
  10. +
  11. Tea
  12. +
  13. + Milk +
      +
    • Coffee
    • +
    • + Tea +
        +
      1. Earl Grey
      2. +
      3. Green
      4. +
      5. Rosboh
      6. +
      +
    • +
    • Milk
    • +
    +
  14. +
  15. Wine
-
Inside table
-
-

delta parameter (d)

- Looks how cool is Open Xml. -
- Now with HtmlToOpenXml, it never been so easy to convert html. -

- If you like it, add me a rating on github -

- - simple text -
- Hello ! - je suis du texte - écrit en oblique. - -
  public void SetContentType(System.Web.HttpRequest request, System.Web.HttpResponse response, String reportName)
+    
Inside table
+
+

delta parameter (d)

+ Looks how cool is Open Xml. +
+ Now with HtmlToOpenXml, it never been so easy to convert html. +

+ If you like it, add me a rating on github +

+ + simple text +
+ Hello ! + je suis du texte + écrit en oblique. + +
  public void SetContentType(System.Web.HttpRequest request, System.Web.HttpResponse response, String reportName)
 {
 	if (request.Browser.Browser.Contains("IE"))
 	{
-		// Replace the %20 to obtain a clean name when saving the file from Word.
+        // Replace the %20 to obtain a clean name when saving the file from Word.
 		encodedFilename =
 		  Uri.EscapeDataString(Path.GetFileNameWithoutExtension(encodedFilename)).Replace("%20", " ")
 			+ Path.GetExtension(encodedFilename);
 	}
 }
 
-
-
+        
+
 Some <Pre> starting one 
 line below! 
-
-

Header placeholder:

-
    -
  1. Item 1
  2. -
  3. Item 2
  4. -
-

Footer Placeholder

-
+
+

Header placeholder:

+
    +
  1. Item 1
  2. +
  3. Item 2
  4. +
+

Footer Placeholder

+
Lorem Ipsum
- diff --git a/src/Html2OpenXml/Expressions/Table/TableCellExpression.cs b/src/Html2OpenXml/Expressions/Table/TableCellExpression.cs index 23bd2e2..7f2141d 100644 --- a/src/Html2OpenXml/Expressions/Table/TableCellExpression.cs +++ b/src/Html2OpenXml/Expressions/Table/TableCellExpression.cs @@ -1,4 +1,4 @@ -/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved +/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved * * This source is subject to the Microsoft Permissive License. * Please see the License.txt file for more information. @@ -10,6 +10,7 @@ * PARTICULAR PURPOSE. */ using System.Collections.Generic; +using System.Globalization; using System.Linq; using AngleSharp.Html.Dom; using DocumentFormat.OpenXml; @@ -59,6 +60,28 @@ protected override void ComposeStyles(ParsingContext context) { base.ComposeStyles(context); + Unit width = styleAttributes.GetUnit("width"); + + if (!width.IsValid) + { + var widthValue = node.GetAttribute("width"); + if (!string.IsNullOrEmpty(widthValue)) + { + width = Unit.Parse(widthValue); + } + } + + if (width.IsValid) + { + cellProperties.TableCellWidth = new TableCellWidth + { + Type = width.Type == UnitMetric.Percent ? TableWidthUnitValues.Pct : TableWidthUnitValues.Dxa, + Width = width.Type == UnitMetric.Percent + ? ((int) (width.Value * 50)).ToString(CultureInfo.InvariantCulture) + : width.ValueInDxa.ToString(CultureInfo.InvariantCulture) + }; + } + // Manage vertical text (only for table cell) string? direction = styleAttributes!["writing-mode"]; if (direction != null) @@ -98,4 +121,4 @@ internal static bool IsValidRowSpan(int rowSpan) // 0 means it extends until the end of the table grouping section return rowSpan == 0 || rowSpan > 1; } -} \ No newline at end of file +} diff --git a/src/Html2OpenXml/Expressions/Table/TableExpression.cs b/src/Html2OpenXml/Expressions/Table/TableExpression.cs index ecb0b9c..84c1d02 100644 --- a/src/Html2OpenXml/Expressions/Table/TableExpression.cs +++ b/src/Html2OpenXml/Expressions/Table/TableExpression.cs @@ -1,4 +1,4 @@ -/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved +/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved * * This source is subject to the Microsoft Permissive License. * Please see the License.txt file for more information. @@ -175,17 +175,11 @@ protected override void ComposeStyles (ParsingContext context) switch (width.Type) { case UnitMetric.Percent: - if (width.Value == 100) + tableProperties.TableWidth = new TableWidth { - // Use Auto=0 instead of Pct=auto - // bug reported by scarhand (https://html2openxml.codeplex.com/workitem/12494) - tableProperties.TableWidth = new() { Type = TableWidthUnitValues.Auto, Width = "0" }; - } - else - { - tableProperties.TableWidth = new() { Type = TableWidthUnitValues.Pct, - Width = (width.Value * 50).ToString(CultureInfo.InvariantCulture) }; - } + Type = TableWidthUnitValues.Pct, + Width = (width.Value * 50).ToString(CultureInfo.InvariantCulture) + }; break; case UnitMetric.Point: case UnitMetric.Pixel: @@ -287,4 +281,4 @@ protected override void ComposeStyles (ParsingContext context) } } } -} \ No newline at end of file +} From b05565254a011a00f0de050d96678653a89ed56f Mon Sep 17 00:00:00 2001 From: Mo Ibrahim Date: Tue, 3 Dec 2024 10:08:32 +0200 Subject: [PATCH 2/2] Fix: Apply comments --- src/Html2OpenXml/Expressions/Table/TableCellExpression.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Html2OpenXml/Expressions/Table/TableCellExpression.cs b/src/Html2OpenXml/Expressions/Table/TableCellExpression.cs index 7f2141d..00d67f7 100644 --- a/src/Html2OpenXml/Expressions/Table/TableCellExpression.cs +++ b/src/Html2OpenXml/Expressions/Table/TableCellExpression.cs @@ -60,11 +60,11 @@ protected override void ComposeStyles(ParsingContext context) { base.ComposeStyles(context); - Unit width = styleAttributes.GetUnit("width"); + Unit width = styleAttributes!.GetUnit("width"); if (!width.IsValid) { - var widthValue = node.GetAttribute("width"); + var widthValue = this.node.GetAttribute("width"); if (!string.IsNullOrEmpty(widthValue)) { width = Unit.Parse(widthValue);