Skip to content

Commit c7ccc18

Browse files
authored
fixed filling of images in the horizontal range (#233)
fix for Merged ranges fixed propagation of row heights from template to generated rows fixed filling of images in the horizontal range
1 parent 6772ecc commit c7ccc18

File tree

13 files changed

+81
-24
lines changed

13 files changed

+81
-24
lines changed

ClosedXML.Report/Excel/XlExtensions.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using ClosedXML.Excel;
77
using ClosedXML.Report.Options;
88
using ClosedXML.Report.Utils;
9+
using MoreLinq;
910

1011
namespace ClosedXML.Report.Excel
1112
{
@@ -122,13 +123,29 @@ internal static KeyValuePair<string, IXLRangeAddress>[] GetRangeParameters(this
122123
/// <param name="range">range</param>
123124
public static IEnumerable<IXLNamedRange> GetContainingNames(this IXLRange range)
124125
{
125-
return range.Worksheet.NamedRanges.Where(x => GetContainingRanges(x, range))
126-
.Union(range.Worksheet.Workbook.NamedRanges.Where(x => GetContainingRanges(x, range)));
126+
return range.Worksheet.NamedRanges
127+
.Union(range.Worksheet.Workbook.NamedRanges)
128+
.Where(x => GetContainingRanges(x, range));
127129
}
128130

129131
private static bool GetContainingRanges(IXLNamedRange x, IXLRange xlRange)
130132
{
131-
return x.Ranges.Where(r => r.Worksheet.Position == xlRange.Worksheet.Position && !r.Equals(xlRange)).Any(xlRange.Contains);
133+
return x.Ranges.Select(GrowToMergedRanges)
134+
.Where(r => r.Worksheet.Position == xlRange.Worksheet.Position && !r.Equals(xlRange))
135+
.Any(xlRange.Contains);
136+
}
137+
138+
public static IXLRange GrowToMergedRanges(this IXLRange range)
139+
{
140+
var sheet = range.Worksheet;
141+
sheet.MergedRanges.Where(range.Intersects)
142+
.ForEach(x =>
143+
{
144+
var xlCells = range.Union(x).Select(c => c.Address)
145+
.OrderBy(c => c.RowNumber).ThenBy(c => c.ColumnNumber).ToArray();
146+
range = sheet.Range(xlCells.First().ToStringFixed(), xlCells.Last().ToStringFixed());
147+
});
148+
return range;
132149
}
133150

134151
/// <summary>

ClosedXML.Report/Options/ImageTag.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public override void Execute(ProcessingContext context)
2727

2828
switch (imgValue)
2929
{
30+
case "":
31+
case null: return;
3032
case Stream stream: picture = xlCell.Worksheet.AddPicture(stream); break;
3133
case string path: picture = xlCell.Worksheet.AddPicture(path); break;
3234
case Bitmap image: picture = xlCell.Worksheet.AddPicture(image); break;

ClosedXML.Report/RangeInterpreter.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,13 @@ string EvalString(string str)
172172
{
173173
foreach (var rng in nr.NamedRange.Ranges)
174174
{
175+
var growedRange = rng.GrowToMergedRanges();
175176
var items = nr.RangeData as object[] ?? nr.RangeData.Cast<object>().ToArray();
176-
var tplt = RangeTemplate.Parse(nr.NamedRange.Name, rng, _errors, _variables);
177+
var tplt = RangeTemplate.Parse(nr.NamedRange.Name, growedRange, _errors, _variables);
177178
using (var buff = tplt.Generate(items))
178179
{
179180
var ranges = nr.NamedRange.Ranges;
180-
var trgtRng = buff.CopyTo(rng);
181+
var trgtRng = buff.CopyTo(growedRange);
181182
ranges.Remove(rng);
182183
ranges.Add(trgtRng);
183184
nr.NamedRange.SetRefersTo(ranges);
@@ -191,9 +192,9 @@ string EvalString(string str)
191192
// refresh ranges for pivot tables
192193
foreach (var pt in range.Worksheet.Workbook.Worksheets.SelectMany(sh => sh.PivotTables))
193194
{
194-
if (pt.SourceRange.Intersects(rng))
195+
if (pt.SourceRange.Intersects(growedRange))
195196
{
196-
pt.SourceRange = rng.Offset(-1, 1, rng.RowCount() + 1, rng.ColumnCount() - 1);
197+
pt.SourceRange = growedRange.Offset(-1, 1, growedRange.RowCount() + 1, growedRange.ColumnCount() - 1);
197198
}
198199
}
199200
}

ClosedXML.Report/RangeTemplate.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ private static RangeTemplate Parse(string name, IXLRange range, TempSheetBuffer
8181
var innerRanges = GetInnerRanges(range).ToArray();
8282

8383
var sheet = range.Worksheet;
84-
8584
for (int iRow = 1; iRow <= result._rowCnt; iRow++)
8685
{
8786
for (int iColumn = 1; iColumn <= result._colCnt; iColumn++)
@@ -240,6 +239,21 @@ private void VerticalTable(object[] items, FormulaEvaluator evaluator)
240239
}
241240
}
242241

242+
// arrage rows height
243+
var worksheet = _rowRange.Worksheet;
244+
var rowNumbers = _cells.Where(xc => xc.XLCell != null && xc.Row <= _rowCnt)
245+
.Select(xc => xc.XLCell.Address.RowNumber)
246+
.Distinct()
247+
.ToArray();
248+
var heights = rowNumbers
249+
.Select(c => worksheet.Row(c).Height)
250+
.ToArray();
251+
var firstRow = rowNumbers.Min();
252+
foreach (var row in Enumerable.Range(rangeStart.RowNumber, _buff.PrevAddress.RowNumber))
253+
{
254+
worksheet.Row(firstRow + row - 1).Height = heights[(row - 1) % heights.Length];
255+
}
256+
243257
if (_isSubrange)
244258
{
245259
_rangeTags.Execute(new ProcessingContext(resultRange, new DataSource(items), evaluator));
@@ -397,6 +411,7 @@ private void HorizontalTable(object[] items, FormulaEvaluator evaluator)
397411
}
398412

399413
tags.Execute(new ProcessingContext(newClmnRng, items[i], evaluator));
414+
tags.Reset();
400415

401416
if (_rowCnt > 1)
402417
_buff.NewColumn(startAddr);
@@ -443,7 +458,7 @@ where TagExtensions.HasTag(value)
443458
tags = _tagsEvaluator.Parse(cell.GetString(), range, cell, out newValue);
444459
cell.Value = newValue;
445460
}
446-
if (cell.Row == _rowCnt)
461+
if (cell.Row > 1 && cell.Row == _rowCnt)
447462
_rangeTags.AddRange(tags);
448463
else
449464
_tags.AddRange(tags);

tests/ClosedXML.Report.Tests/ClosedXML.Report.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>net452</TargetFrameworks>
4-
<LangVersion>7.1</LangVersion>
4+
<LangVersion>Latest</LangVersion>
55
<Configurations>Debug;Release;Release.Signed</Configurations>
66
<PackageLicenseUrl>https://github.com/ClosedXML/ClosedXML.Report/blob/master/LICENSE</PackageLicenseUrl>
77
<PackageProjectUrl>https://github.com/ClosedXML/ClosedXML.Report</PackageProjectUrl>

tests/ClosedXML.Report.Tests/GroupTagTests.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Drawing;
1+
using System;
2+
using System.Drawing;
23
using System.Linq;
34
using ClosedXML.Report.Tests.TestModels;
45
using LinqToDB;
@@ -27,6 +28,7 @@ public GroupTagTests(ITestOutputHelper output) : base(output)
2728
InlineData("tLists6_count.xlsx"),
2829
InlineData("tLists7_image.xlsx"),
2930
InlineData("tPage1_options.xlsx"),
31+
InlineData("tLists7_horizontal_images.xlsx"),
3032
]
3133
public void Simple(string templateFile)
3234
{
@@ -35,19 +37,11 @@ public void Simple(string templateFile)
3537
{
3638
using (var db = new DbDemos())
3739
{
38-
var cust = db.customers.LoadWith(x => x.Orders).OrderBy(c => c.CustNo).First(x=>x.CustNo == 1356);
40+
var cust = db.customers.LoadWith(x=>x.Orders.First().Items).OrderBy(c => c.CustNo).First(x=>x.CustNo == 1356);
3941
cust.Logo = Resource.toms_diving_center;
40-
cust.Orders.ForEach(x =>
41-
{
42-
switch (x.PaymentMethod)
43-
{
44-
case "Visa": x.PaymentImage = Resource.card; break;
45-
case "Cash": x.PaymentImage = Resource.cash; break;
46-
case "Credit": x.PaymentImage = Resource.bank; break;
47-
}
48-
});
4942
tpl.AddVariable("MoreOrders", cust.Orders.Take(5));
5043
tpl.AddVariable(cust);
44+
tpl.AddVariable("ItemsHeader", Enumerable.Range(1, cust.Orders.Max(x => x.Items.Count)).Select(x => $"Item {x}"));
5145
}
5246
tpl.AddVariable("Tax", 13);
5347
},

tests/ClosedXML.Report.Tests/Resource.Designer.cs

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/ClosedXML.Report.Tests/Resource.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@
127127
<data name="cash" type="System.Resources.ResXFileRef, System.Windows.Forms">
128128
<value>Resources\cash.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
129129
</data>
130+
<data name="checkmark" type="System.Resources.ResXFileRef, System.Windows.Forms">
131+
<value>Resources\checkmark.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
132+
</data>
130133
<data name="toms_diving_center" type="System.Resources.ResXFileRef, System.Windows.Forms">
131134
<value>Resources\toms_diving_center.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
132135
</data>
Loading

tests/ClosedXML.Report.Tests/TestModels/Order.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ public partial class order
1313
[Association(ThisKey = "OrderNo", OtherKey = "OrderNo", IsBackReference = true)]
1414
public List<item> Items { get; set; }
1515

16-
public Bitmap PaymentImage { get; set; }
16+
public Bitmap PaymentImage
17+
{
18+
get
19+
{
20+
switch (PaymentMethod)
21+
{
22+
case "Visa": return Resource.card;
23+
case "Cash": return Resource.cash;
24+
case "Credit": return Resource.bank;
25+
default: return null;
26+
}
27+
}
28+
}
1729
}
1830
}

0 commit comments

Comments
 (0)