Skip to content

Commit 5aa63a9

Browse files
Added StyleOptions class to OpenXmlConfiguration to allow more direct control over cell styles (#761)
* Code cleanup * Added StyleOptions class to OpenXmlConfiguration to allow more direct control over cell styles The first (and only so far) option implemented is WrapCellContents, that when set to true makes overflowing text wrap to the next line * Update DefaultSheetStyleBuilder.cs Signed-off-by: Wei Lin <[email protected]> --------- Signed-off-by: Wei Lin <[email protected]> Co-authored-by: Wei Lin <[email protected]>
1 parent 1cead69 commit 5aa63a9

16 files changed

+104
-130
lines changed

src/MiniExcel/Attributes/ExcelColumnAttribute.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,10 @@ public class ExcelColumnAttribute : Attribute
1212
internal int FormatId { get; set; } = -1;
1313

1414
public string Name { get; set; }
15-
1615
public string[] Aliases { get; set; }
17-
1816
public double Width { get; set; } = 9.28515625;
19-
2017
public string Format { get; set; }
21-
2218
public bool Ignore { get; set; }
23-
2419
public ColumnType Type { get; set; } = ColumnType.Value;
2520

2621
public int Index
@@ -38,16 +33,11 @@ public string IndexName
3833
private void Init(int index, string columnName = null)
3934
{
4035
if (index < 0)
41-
{
42-
throw new ArgumentOutOfRangeException(nameof(index), index,
43-
$"Column index {index} must be greater or equal to zero.");
44-
}
36+
throw new ArgumentOutOfRangeException(nameof(index), index, $"Column index {index} must be greater or equal to zero.");
4537

4638
if (_xName == null)
47-
if (columnName != null)
48-
_xName = columnName;
49-
else
50-
_xName = ColumnHelper.GetAlphabetColumnName(index);
39+
_xName = columnName ?? ColumnHelper.GetAlphabetColumnName(index);
40+
5141
_index = index;
5242
}
5343
}
@@ -57,7 +47,6 @@ public enum ColumnType { Value, Formula }
5747
public class DynamicExcelColumn : ExcelColumnAttribute
5848
{
5949
public string Key { get; set; }
60-
6150
public Func<object, object> CustomFormatter { get; set; }
6251

6352
public DynamicExcelColumn(string key)

src/MiniExcel/OpenXml/Config.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace MiniExcelLibs.OpenXml
22
{
3-
internal class Config
3+
internal static class Config
44
{
55
public const string SpreadsheetmlXmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
66
public const string SpreadsheetmlXmlStrictns = "http://purl.oclc.org/ooxml/spreadsheetml/main";

src/MiniExcel/OpenXml/Constants/ExcelFileNames.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ internal static class ExcelFileNames
99
internal const string Styles = "xl/styles.xml";
1010
internal const string Workbook = "xl/workbook.xml";
1111
internal const string WorkbookRels = "xl/_rels/workbook.xml.rels";
12-
internal static string SheetRels(int sheetId)
13-
=> $"xl/worksheets/_rels/sheet{sheetId}.xml.rels";
14-
internal static string Drawing(int sheetIndex)
15-
=> $"xl/drawings/drawing{sheetIndex + 1}.xml";
16-
internal static string DrawingRels(int sheetIndex)
17-
=> $"xl/drawings/_rels/drawing{sheetIndex + 1}.xml.rels";
12+
13+
internal static string SheetRels(int sheetId) => $"xl/worksheets/_rels/sheet{sheetId}.xml.rels";
14+
internal static string Drawing(int sheetIndex) => $"xl/drawings/drawing{sheetIndex + 1}.xml";
15+
internal static string DrawingRels(int sheetIndex) => $"xl/drawings/_rels/drawing{sheetIndex + 1}.xml.rels";
1816
}
1917
}

src/MiniExcel/OpenXml/Constants/ExcelXml.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ internal static class ExcelXml
66
{
77
static ExcelXml()
88
{
9-
DefaultRels = ExcelOpenXmlUtils.MinifyXml( DefaultRels);
9+
DefaultRels = ExcelOpenXmlUtils.MinifyXml(DefaultRels);
1010
DefaultWorkbookXml = ExcelOpenXmlUtils.MinifyXml(DefaultWorkbookXml);
1111
DefaultWorkbookXmlRels = ExcelOpenXmlUtils.MinifyXml(DefaultWorkbookXmlRels);
1212
DefaultSheetRelXml = ExcelOpenXmlUtils.MinifyXml(DefaultSheetRelXml);
1313
DefaultDrawing = ExcelOpenXmlUtils.MinifyXml(DefaultDrawing);
1414
}
1515

1616

17-
internal static readonly string EmptySheetXml = $@"<?xml version=""1.0"" encoding=""utf-8""?><x:worksheet xmlns:x=""http://schemas.openxmlformats.org/spreadsheetml/2006/main""><x:dimension ref=""A1""/><x:sheetData></x:sheetData></x:worksheet>";
17+
internal const string EmptySheetXml = @"<?xml version=""1.0"" encoding=""utf-8""?><x:worksheet xmlns:x=""http://schemas.openxmlformats.org/spreadsheetml/2006/main""><x:dimension ref=""A1""/><x:sheetData></x:sheetData></x:worksheet>";
1818

1919
internal static readonly string DefaultRels = @"<?xml version=""1.0"" encoding=""utf-8""?>
2020
<Relationships xmlns=""http://schemas.openxmlformats.org/package/2006/relationships"">
@@ -40,22 +40,24 @@ static ExcelXml()
4040
<Relationships xmlns=""http://schemas.openxmlformats.org/package/2006/relationships"">
4141
{{format}}
4242
</Relationships>";
43+
4344
internal static readonly string DefaultDrawing = @"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>
4445
<xdr:wsDr xmlns:a=""http://schemas.openxmlformats.org/drawingml/2006/main""
4546
xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships""
4647
xmlns:xdr=""http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"">
4748
{{format}}
4849
</xdr:wsDr>";
49-
internal static readonly string DefaultDrawingXmlRels = @"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>
50+
51+
internal const string DefaultDrawingXmlRels = @"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>
5052
<Relationships xmlns=""http://schemas.openxmlformats.org/package/2006/relationships"">
5153
{{format}}
5254
</Relationships>";
5355

54-
internal static readonly string DefaultSharedString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"0\" uniqueCount=\"0\"></sst>";
56+
internal const string DefaultSharedString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" count=\"0\" uniqueCount=\"0\"></sst>";
5557

56-
internal static readonly string StartTypes = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Types xmlns=""http://schemas.openxmlformats.org/package/2006/content-types""><Default ContentType=""application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"" Extension=""bin""/><Default ContentType=""application/xml"" Extension=""xml""/><Default ContentType=""image/jpeg"" Extension=""jpg""/><Default ContentType=""image/png"" Extension=""png""/><Default ContentType=""image/gif"" Extension=""gif""/><Default ContentType=""application/vnd.openxmlformats-package.relationships+xml"" Extension=""rels""/>";
58+
internal const string StartTypes = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Types xmlns=""http://schemas.openxmlformats.org/package/2006/content-types""><Default ContentType=""application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"" Extension=""bin""/><Default ContentType=""application/xml"" Extension=""xml""/><Default ContentType=""image/jpeg"" Extension=""jpg""/><Default ContentType=""image/png"" Extension=""png""/><Default ContentType=""image/gif"" Extension=""gif""/><Default ContentType=""application/vnd.openxmlformats-package.relationships+xml"" Extension=""rels""/>";
5759
internal static string ContentType(string contentType, string partName) => $"<Override ContentType=\"{contentType}\" PartName=\"/{partName}\" />";
58-
internal static readonly string EndTypes = "</Types>";
60+
internal const string EndTypes = "</Types>";
5961

6062
internal static string WorksheetRelationship(SheetDto sheetDto)
6163
=> $@"<Relationship Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"" Target=""/{sheetDto.Path}"" Id=""{sheetDto.ID}"" />";

src/MiniExcel/OpenXml/Constants/WorksheetXml.cs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
using System.Globalization;
22
using MiniExcelLibs.Attributes;
3-
using System.Linq;
43

54
namespace MiniExcelLibs.OpenXml.Constants
65
{
7-
internal class WorksheetXml
6+
internal static class WorksheetXml
87
{
98
internal const string StartWorksheet = @"<?xml version=""1.0"" encoding=""utf-8""?><x:worksheet xmlns:x=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"">";
109
internal const string StartWorksheetWithRelationship = @"<?xml version=""1.0"" encoding=""utf-8""?><x:worksheet xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"" xmlns:x=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" >";
@@ -36,40 +35,34 @@ internal static string StartPane( int? xSplit, int? ySplit, string topLeftCell,
3635

3736
internal static string PaneSelection( string pane, string activeCell, string sqref)
3837
=> string.Concat(
39-
$"<x:selection",
38+
"<x:selection",
4039
$" pane=\"{pane}\"",
4140
string.IsNullOrWhiteSpace(activeCell) ? string.Empty : $" activeCell=\"{activeCell}\"",
4241
string.IsNullOrWhiteSpace(sqref) ? string.Empty : $" sqref=\"{sqref}\"",
4342
"/>");
4443

45-
internal static string StartRow(int rowIndex)
46-
=> $"<x:row r=\"{rowIndex}\">";
44+
internal static string StartRow(int rowIndex) => $"<x:row r=\"{rowIndex}\">";
4745
internal const string EndRow = "</x:row>";
48-
4946
internal const string StartCols = "<x:cols>";
47+
5048
internal static string Column(int colIndex, double columnWidth)
5149
=> $@"<x:col min=""{colIndex}"" max=""{colIndex}"" width=""{columnWidth.ToString(CultureInfo.InvariantCulture)}"" customWidth=""1"" />";
52-
53-
50+
5451
private static readonly int _maxColumnLength = Column(int.MaxValue, double.MaxValue).Length;
5552

56-
public static int GetColumnPlaceholderLength(int columnCount)
57-
{
58-
return StartCols.Length + (_maxColumnLength * columnCount) + EndCols.Length;
59-
}
53+
public static int GetColumnPlaceholderLength(int columnCount)
54+
=> StartCols.Length + (_maxColumnLength * columnCount) + EndCols.Length;
6055

6156
internal const string EndCols = "</x:cols>";
6257

6358
internal static string EmptyCell(string cellReference, string styleIndex)
6459
=> $"<x:c r=\"{cellReference}\" s=\"{styleIndex}\"></x:c>";
60+
6561
//t check avoid format error ![image](https://user-images.githubusercontent.com/12729184/118770190-9eee3480-b8b3-11eb-9f5a-87a439f5e320.png)
6662
internal static string Cell(string cellReference, string cellType, string styleIndex, string cellValue, bool preserveSpace = false, ColumnType columnType = ColumnType.Value)
6763
=> $"<x:c r=\"{cellReference}\"{(cellType == null ? string.Empty : $" t=\"{cellType}\"")} s=\"{styleIndex}\"{(preserveSpace ? " xml:space=\"preserve\"" : string.Empty)}><x:{(columnType == ColumnType.Formula ? "f" : "v")}>{cellValue}</x:{(columnType == ColumnType.Formula ? "f" : "v")}></x:c>";
6864

69-
internal static string Autofilter(string dimensionRef)
70-
=> $"<x:autoFilter ref=\"{dimensionRef}\" />";
71-
72-
internal static string Drawing(int sheetIndex)
73-
=> $"<x:drawing r:id=\"drawing{sheetIndex}\" />";
65+
internal static string Autofilter(string dimensionRef) => $"<x:autoFilter ref=\"{dimensionRef}\" />";
66+
internal static string Drawing(int sheetIndex) => $"<x:drawing r:id=\"drawing{sheetIndex}\" />";
7467
}
7568
}

src/MiniExcel/OpenXml/ExcelOpenXmlSheetReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public ExcelOpenXmlSheetReader(Stream stream, IConfiguration configuration, bool
4242
public IEnumerable<IDictionary<string, object>> Query(bool useHeaderRow, string sheetName, string startCell)
4343
{
4444
if (!ReferenceHelper.ParseReference(startCell, out var startColumnIndex, out var startRowIndex))
45-
throw new InvalidDataException($"startCell {startCell} is Invalid");
45+
throw new ArgumentException($"Value {startCell} is not a valid cell reference.");
4646
startColumnIndex--;
4747
startRowIndex--;
4848

src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.Async.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ private async Task GenerateStylesXmlAsync(CancellationToken cancellationToken)
434434
builder = new MinimalSheetStyleBuilder(context);
435435
break;
436436
case TableStyles.Default:
437-
builder = new DefaultSheetStyleBuilder(context);
437+
builder = new DefaultSheetStyleBuilder(context, _configuration.StyleOptions);
438438
break;
439439
}
440440
var result = await builder.BuildAsync(cancellationToken);

src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace MiniExcelLibs.OpenXml
1818
internal partial class ExcelOpenXmlSheetWriter : IExcelWriter
1919
{
2020
private readonly MiniExcelZipArchive _archive;
21-
private readonly static UTF8Encoding _utf8WithBom = new UTF8Encoding(true);
21+
private static readonly UTF8Encoding _utf8WithBom = new UTF8Encoding(true);
2222
private readonly OpenXmlConfiguration _configuration;
2323
private readonly Stream _stream;
2424
private readonly bool _printHeader;
@@ -45,10 +45,6 @@ public ExcelOpenXmlSheetWriter(Stream stream, object value, string sheetName, IC
4545
_defaultSheetName = sheetName;
4646
}
4747

48-
public ExcelOpenXmlSheetWriter()
49-
{
50-
}
51-
5248
public int[] SaveAs()
5349
{
5450
GenerateDefaultOpenXml();
@@ -175,7 +171,7 @@ private static long WriteDimensionPlaceholder(MiniExcelStreamWriter writer)
175171
return dimensionPlaceholderPostition;
176172
}
177173

178-
private void WriteDimension(MiniExcelStreamWriter writer, int maxRowIndex, int maxColumnIndex, long placeholderPosition)
174+
private static void WriteDimension(MiniExcelStreamWriter writer, int maxRowIndex, int maxColumnIndex, long placeholderPosition)
179175
{
180176
// Flush and save position so that we can get back again.
181177
var position = writer.Flush();
@@ -378,36 +374,32 @@ private void WriteCell(MiniExcelStreamWriter writer, string cellReference, strin
378374
private void GenerateEndXml()
379375
{
380376
AddFilesToZip();
381-
382377
GenerateDrawinRelXml();
383-
384378
GenerateDrawingXml();
385-
386379
GenerateWorkbookXml();
387-
388380
GenerateContentTypesXml();
389381
}
390382

391383
private void AddFilesToZip()
392384
{
393385
foreach (var item in _files)
394386
{
395-
this.CreateZipEntry(item.Path, item.Byte);
387+
CreateZipEntry(item.Path, item.Byte);
396388
}
397389
}
398390

399391
private void GenerateStylesXml()
400392
{
401393
using (var context = new SheetStyleBuildContext(_zipDictionary, _archive, _utf8WithBom, _configuration.DynamicColumns))
402394
{
403-
var builder = (ISheetStyleBuilder)null;
395+
ISheetStyleBuilder builder = null;
404396
switch (_configuration.TableStyles)
405397
{
406398
case TableStyles.None:
407399
builder = new MinimalSheetStyleBuilder(context);
408400
break;
409401
case TableStyles.Default:
410-
builder = new DefaultSheetStyleBuilder(context);
402+
builder = new DefaultSheetStyleBuilder(context, _configuration.StyleOptions);
411403
break;
412404
}
413405
var result = builder?.Build();

src/MiniExcel/OpenXml/MiniExcelStreamWriter.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,26 @@ internal class MiniExcelStreamWriter : IDisposable
1010
private readonly Encoding _encoding;
1111
private readonly StreamWriter _streamWriter;
1212
private bool disposedValue;
13+
1314
public MiniExcelStreamWriter(Stream stream, Encoding encoding, int bufferSize)
1415
{
15-
this._stream = stream;
16-
this._encoding = encoding;
17-
this._streamWriter = new StreamWriter(stream, this._encoding, bufferSize);
16+
_stream = stream;
17+
_encoding = encoding;
18+
_streamWriter = new StreamWriter(stream, _encoding, bufferSize);
1819
}
1920
public void Write(string content)
2021
{
2122
if (string.IsNullOrEmpty(content))
2223
return;
23-
this._streamWriter.Write(content);
24+
25+
_streamWriter.Write(content);
2426
}
2527

2628
public long WriteAndFlush(string content)
2729
{
28-
this.Write(content);
29-
this._streamWriter.Flush();
30-
return this._streamWriter.BaseStream.Position;
30+
Write(content);
31+
_streamWriter.Flush();
32+
return _streamWriter.BaseStream.Position;
3133
}
3234

3335
public void WriteWhitespace(int length)
@@ -37,20 +39,20 @@ public void WriteWhitespace(int length)
3739

3840
public long Flush()
3941
{
40-
this._streamWriter.Flush();
41-
return this._streamWriter.BaseStream.Position;
42+
_streamWriter.Flush();
43+
return _streamWriter.BaseStream.Position;
4244
}
4345

4446
public void SetPosition(long position)
4547
{
46-
this._streamWriter.BaseStream.Position = position;
48+
_streamWriter.BaseStream.Position = position;
4749
}
4850

4951
protected virtual void Dispose(bool disposing)
5052
{
5153
if (!disposedValue)
5254
{
53-
this._streamWriter?.Dispose();
55+
_streamWriter?.Dispose();
5456
disposedValue = true;
5557
}
5658
}

src/MiniExcel/OpenXml/Models/FileDto.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ internal class FileDto
66
{
77
internal string ID { get; set; } = $"R{Guid.NewGuid():N}";
88
internal string Extension { get; set; }
9-
internal string Path { get { return $"xl/media/{ID}.{Extension}"; } }
10-
internal string Path2 { get { return $"/xl/media/{ID}.{Extension}"; } }
9+
internal string Path => $"xl/media/{ID}.{Extension}";
10+
internal string Path2 => $"/xl/media/{ID}.{Extension}";
1111
internal byte[] Byte { get; set; }
1212
internal int RowIndex { get; set; }
1313
internal int CellIndex { get; set; }
14-
internal bool IsImage { get; set; } = false;
14+
internal bool IsImage { get; set; }
1515
internal int SheetId { get; set; }
1616
}
1717
}

0 commit comments

Comments
 (0)