Skip to content

Commit ad459e3

Browse files
authored
Merge pull request #180 from MoIbrahim10/fix-table-percentage-widths
Fix: Apply 100 percentage widths to tables and percentage widths cells
2 parents aec86c6 + b055652 commit ad459e3

File tree

5 files changed

+141
-98
lines changed

5 files changed

+141
-98
lines changed

HtmlToOpenXml.sln

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,33 @@ EndProject
1414
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlToOpenXml.Tests", "test\HtmlToOpenXml.Tests\HtmlToOpenXml.Tests.csproj", "{CA0A68E0-45A0-4A01-A061-F951D93D6906}"
1515
EndProject
1616
Global
17-
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18-
Debug|Any CPU = Debug|Any CPU
19-
Release|Any CPU = Release|Any CPU
20-
EndGlobalSection
21-
GlobalSection(ProjectConfigurationPlatforms) = postSolution
22-
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23-
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.Build.0 = Debug|Any CPU
24-
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.ActiveCfg = Release|Any CPU
25-
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.Build.0 = Release|Any CPU
26-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.Build.0 = Debug|Any CPU
28-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.ActiveCfg = Release|Any CPU
29-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.Build.0 = Release|Any CPU
30-
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31-
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.Build.0 = Debug|Any CPU
32-
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.ActiveCfg = Release|Any CPU
33-
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.Build.0 = Release|Any CPU
34-
EndGlobalSection
35-
GlobalSection(SolutionProperties) = preSolution
36-
HideSolutionNode = FALSE
37-
EndGlobalSection
38-
GlobalSection(NestedProjects) = preSolution
39-
{EF700F30-C9BB-49A6-912C-E3B77857B514} = {58520A98-BA53-4BA4-AAE3-786AA21331D6}
40-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A}
41-
{CA0A68E0-45A0-4A01-A061-F951D93D6906} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A}
42-
EndGlobalSection
43-
GlobalSection(ExtensibilityGlobals) = postSolution
44-
SolutionGuid = {14EE1026-6507-4295-9FEE-67A55C3849CE}
45-
EndGlobalSection
17+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18+
Debug|Any CPU = Debug|Any CPU
19+
Release|Any CPU = Release|Any CPU
20+
EndGlobalSection
21+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
22+
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.ActiveCfg = Release|Any CPU
25+
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.Build.0 = Release|Any CPU
30+
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31+
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.Build.0 = Debug|Any CPU
32+
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.ActiveCfg = Release|Any CPU
33+
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.Build.0 = Release|Any CPU
34+
EndGlobalSection
35+
GlobalSection(SolutionProperties) = preSolution
36+
HideSolutionNode = FALSE
37+
EndGlobalSection
38+
GlobalSection(NestedProjects) = preSolution
39+
{EF700F30-C9BB-49A6-912C-E3B77857B514} = {58520A98-BA53-4BA4-AAE3-786AA21331D6}
40+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A}
41+
{CA0A68E0-45A0-4A01-A061-F951D93D6906} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A}
42+
EndGlobalSection
43+
GlobalSection(ExtensibilityGlobals) = postSolution
44+
SolutionGuid = {14EE1026-6507-4295-9FEE-67A55C3849CE}
45+
EndGlobalSection
4646
EndGlobal

examples/Demo/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,4 @@ static void AssertThatOpenXmlDocumentIsValid(WordprocessingDocument wpDoc)
7474
Console.ReadLine();
7575
}
7676
}
77-
}
77+
}

examples/Demo/Resources/CompleteRunTest.html

Lines changed: 80 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@
44
<title></title>
55
</head>
66
<body>
7+
8+
<table style="width: 100%; border-collapse: collapse; margin: 20px auto; border: 1px solid #ccc;">
9+
<tr style="background-color: #f4f4f4; text-align: left;">
10+
<th style="width: 10%; border: 1px solid #ccc; padding: 8px;">Column 1</th>
11+
<th style="width: 60%; border: 1px solid #ccc; padding: 8px;">Column 2</th>
12+
<th style="width: 30%; border: 1px solid #ccc; padding: 8px;">Column 3</th>
13+
</tr>
14+
<tr>
15+
<td style="width: 10%; border: 1px solid #ccc; padding: 8px;">Row 1, Cell 1</td>
16+
<td style="width: 60%; border: 1px solid #ccc; padding: 8px;">Row 1, Cell 2</td>
17+
<td style="width: 30%; border: 1px solid #ccc; padding: 8px;">Row 1, Cell 3</td>
18+
</tr>
19+
<tr>
20+
<td style="width: 10%; border: 1px solid #ccc; padding: 8px;">Row 2, Cell 1</td>
21+
<td style="width: 60%; border: 1px solid #ccc; padding: 8px;">Row 2, Cell 2</td>
22+
<td style="width: 30%; border: 1px solid #ccc; padding: 8px;">Row 2, Cell 3</td>
23+
</tr>
24+
</table>
25+
726
<h1></h1>
827
<h1>Heading 1</h1>
928
<h2>Heading 2</h2>
@@ -15,8 +34,11 @@ <h5>Heading 5</h5>
1534
<span style="font-variant: small-caps"> Small caps</span><br />
1635
<strike>Strike</strike> <span style="text-decoration: line-through"> Line Through</span> <span style="text-decoration: overline"> Overline</span> <span style="text-decoration: underline"> Underline</span><br />
1736
<b> Bold</b><br />
18-
<span>This is a <b>bold
19-
</b>text</span>
37+
<span>
38+
This is a <b>
39+
bold
40+
</b>text
41+
</span>
2042
<span style="font-weight: bold">Bold</span><br />
2143
<span style="font-weight: bolder">Bolder</span><br />
2244
<span style="font-weight: lighter">Lighter</span><br />
@@ -47,7 +69,8 @@ <h5>Heading 5</h5>
4769
<a href="www.github.com"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" /></a>
4870

4971
<!-- multiline images -->
50-
<p><img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8l
72+
<p>
73+
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8l
5174
JCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/wAALCABVAEABAREA/8QAHwAA
5275
AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR
5376
BRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RF
@@ -88,7 +111,8 @@ <h5>Heading 5</h5>
88111
OfDEXhz/AIRbxtAkV1pYNrJHNC0qSbPlDKQDg8e3tVD4Q6BKPGmp67Y2lxbaJ5ckVo04IMgZ
89112
1KjnqAByfXFezMiv95Q2PUZoCKOigY9BSkA9QDjmgqGBDAEHsaia0tnQxtbxMjdVKAg0W9pb
90113
Wilba3ihB6iNAufyoltLaZw8tvFIw6FkBNSgADA4FLRRRRRRRX//2Q==
91-
"></p>
114+
">
115+
</p>
92116

93117
<img src="https://www.w3schools.com/tags/smiley.gif" alt="Smiley face" width="42" height="42">
94118

@@ -102,79 +126,81 @@ <h5>Heading 5</h5>
102126
<br />
103127

104128

105-
<blockquote cite="http://www.worldwildlife.org/who/index.html">
106-
For 50 years, <b>WWF</b> 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.
107-
</blockquote>
129+
<blockquote cite="http://www.worldwildlife.org/who/index.html">
130+
For 50 years, <b>WWF</b> 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.
131+
</blockquote>
108132

109-
<br class="ibp-rteFontSize-5"/><span style="font-size: 16.9px">My Text </span>
133+
<br class="ibp-rteFontSize-5" /><span style="font-size: 16.9px">My Text </span>
110134

111-
<p>An ordered list:</p>
135+
<p>An ordered list:</p>
112136
<ol>
113-
<li>Coffee</li>
114-
<li>Tea</li>
115-
<li>Milk
116-
<ul>
117-
<li>Coffee</li>
118-
<li>Tea
119-
<ol>
120-
<li>Earl Grey</li>
121-
<li>Green</li>
122-
<li>Rosboh</li>
123-
</ol>
124-
</li>
125-
<li>Milk</li>
126-
</ul>
127-
</li>
128-
<li>Wine</li>
137+
<li>Coffee</li>
138+
<li>Tea</li>
139+
<li>
140+
Milk
141+
<ul>
142+
<li>Coffee</li>
143+
<li>
144+
Tea
145+
<ol>
146+
<li>Earl Grey</li>
147+
<li>Green</li>
148+
<li>Rosboh</li>
149+
</ol>
150+
</li>
151+
<li>Milk</li>
152+
</ul>
153+
</li>
154+
<li>Wine</li>
129155
</ol>
130156

131-
<table border=1><tr><td>Inside table</td></tr></table>
132-
<hr />
133-
<p>delta parameter (<span style='font-family:Symbol'>d</span>)</p>
134-
Looks how cool is <font size="x-large" color="maroon"><b>Open Xml</b></font>.
135-
<hr />
136-
Now with <font color="red"><u>HtmlToOpenXml</u></font>, it never been so easy to convert html.
137-
<p>
138-
If you like it, add me a rating on <a href="https://github.com/onizet/html2openxml">github</a>
139-
</p>
140-
141-
simple text
142-
<div style="page-orientation: landscape; page-break-before: always">
143-
Hello !
144-
je suis du texte
145-
<span style="font-style: oblique">écrit en oblique.</span>
146-
147-
<pre lang="fr-FR" class="c#"> public void SetContentType(System.Web.HttpRequest request, System.Web.HttpResponse response, String reportName)
157+
<table border=1><tr><td>Inside table</td></tr></table>
158+
<hr />
159+
<p>delta parameter (<span style='font-family:Symbol'>d</span>)</p>
160+
Looks how cool is <font size="x-large" color="maroon"><b>Open Xml</b></font>.
161+
<hr />
162+
Now with <font color="red"><u>HtmlToOpenXml</u></font>, it never been so easy to convert html.
163+
<p>
164+
If you like it, add me a rating on <a href="https://github.com/onizet/html2openxml">github</a>
165+
</p>
166+
167+
simple text
168+
<div style="page-orientation: landscape; page-break-before: always">
169+
Hello !
170+
je suis du texte
171+
<span style="font-style: oblique">écrit en oblique.</span>
172+
173+
<pre lang="fr-FR" class="c#"> public void SetContentType(System.Web.HttpRequest request, System.Web.HttpResponse response, String reportName)
148174
{
149175
if (request.Browser.Browser.Contains(&quot;IE&quot;))
150176
{
151-
<span style="color:Green">// Replace the %20 to obtain a clean name when saving the file from Word.</span>
177+
<span style="color:Green">// Replace the %20 to obtain a clean name when saving the file from Word.</span>
152178
encodedFilename =
153179
Uri.EscapeDataString(Path.GetFileNameWithoutExtension(encodedFilename)).Replace(&quot;%20&quot;, &quot; &quot;)
154180
+ Path.GetExtension(encodedFilename);
155181
}
156182
}
157183
</pre>
158-
<hr/>
159-
<pre>
184+
<hr />
185+
<pre>
160186
Some &lt;Pre&gt; starting one
161187
line below! </pre>
162188

163189
</div>
164190

165191
<div style='margin-top: 20px; border: 1px dashed rgba(0, 0, 0, 0.4); background: olive; color: white; display: flex; gap: 5px; padding: 6px 8px; font-size: 14px;'>
166-
<div>
167-
<p>Header placeholder:</p>
168-
<ol>
169-
<li>Item 1</li>
170-
<li>Item 2</li>
171-
</ol>
172-
<p style='text-indent: 4.5em'>Footer Placeholder</p>
173-
</div>
192+
<div>
193+
<p>Header placeholder:</p>
194+
<ol>
195+
<li>Item 1</li>
196+
<li>Item 2</li>
197+
</ol>
198+
<p style='text-indent: 4.5em'>Footer Placeholder</p>
199+
</div>
174200
</div>
175201

176202
<div style="border: 1px dashed salmon; margin: 1em">Lorem Ipsum</div>
177-
<!--<div style="page-break-before: always">
203+
<!--<div style="page-break-before: always">
178204
New page
179205
</div>-->
180206
</body>

src/Html2OpenXml/Expressions/Table/TableCellExpression.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved
1+
/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved
22
*
33
* This source is subject to the Microsoft Permissive License.
44
* Please see the License.txt file for more information.
@@ -10,6 +10,7 @@
1010
* PARTICULAR PURPOSE.
1111
*/
1212
using System.Collections.Generic;
13+
using System.Globalization;
1314
using System.Linq;
1415
using AngleSharp.Html.Dom;
1516
using DocumentFormat.OpenXml;
@@ -59,6 +60,28 @@ protected override void ComposeStyles(ParsingContext context)
5960
{
6061
base.ComposeStyles(context);
6162

63+
Unit width = styleAttributes!.GetUnit("width");
64+
65+
if (!width.IsValid)
66+
{
67+
var widthValue = this.node.GetAttribute("width");
68+
if (!string.IsNullOrEmpty(widthValue))
69+
{
70+
width = Unit.Parse(widthValue);
71+
}
72+
}
73+
74+
if (width.IsValid)
75+
{
76+
cellProperties.TableCellWidth = new TableCellWidth
77+
{
78+
Type = width.Type == UnitMetric.Percent ? TableWidthUnitValues.Pct : TableWidthUnitValues.Dxa,
79+
Width = width.Type == UnitMetric.Percent
80+
? ((int) (width.Value * 50)).ToString(CultureInfo.InvariantCulture)
81+
: width.ValueInDxa.ToString(CultureInfo.InvariantCulture)
82+
};
83+
}
84+
6285
// Manage vertical text (only for table cell)
6386
string? direction = styleAttributes!["writing-mode"];
6487
if (direction != null)
@@ -98,4 +121,4 @@ internal static bool IsValidRowSpan(int rowSpan)
98121
// 0 means it extends until the end of the table grouping section
99122
return rowSpan == 0 || rowSpan > 1;
100123
}
101-
}
124+
}

src/Html2OpenXml/Expressions/Table/TableExpression.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved
1+
/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved
22
*
33
* This source is subject to the Microsoft Permissive License.
44
* Please see the License.txt file for more information.
@@ -175,17 +175,11 @@ protected override void ComposeStyles (ParsingContext context)
175175
switch (width.Type)
176176
{
177177
case UnitMetric.Percent:
178-
if (width.Value == 100)
178+
tableProperties.TableWidth = new TableWidth
179179
{
180-
// Use Auto=0 instead of Pct=auto
181-
// bug reported by scarhand (https://html2openxml.codeplex.com/workitem/12494)
182-
tableProperties.TableWidth = new() { Type = TableWidthUnitValues.Auto, Width = "0" };
183-
}
184-
else
185-
{
186-
tableProperties.TableWidth = new() { Type = TableWidthUnitValues.Pct,
187-
Width = (width.Value * 50).ToString(CultureInfo.InvariantCulture) };
188-
}
180+
Type = TableWidthUnitValues.Pct,
181+
Width = (width.Value * 50).ToString(CultureInfo.InvariantCulture)
182+
};
189183
break;
190184
case UnitMetric.Point:
191185
case UnitMetric.Pixel:
@@ -287,4 +281,4 @@ protected override void ComposeStyles (ParsingContext context)
287281
}
288282
}
289283
}
290-
}
284+
}

0 commit comments

Comments
 (0)