Skip to content

Commit 300cae6

Browse files
Mirrors PR 906 on the maintenance branch
* Fixes issue #905 on the maintenance branch Co-Authored-By: Amos <[email protected]> --------- Co-authored-by: Amos <[email protected]>
1 parent b20a5fd commit 300cae6

File tree

5 files changed

+213
-163
lines changed

5 files changed

+213
-163
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,5 +401,6 @@ FodyWeavers.xsd
401401
/BenchmarkDotNet.Artifacts
402402
/tests/MiniExcel.Tests.AspNetMvc/packages
403403
/TestTemplate
404+
/tests/data
404405
/tests/MiniExcelTests/TemplateOptimization
405406
/samples/xlsx/Test_EnableWriteFilePath.xlsx

src/MiniExcel/Csv/CsvWriter.cs

Lines changed: 69 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -109,74 +109,92 @@ private async Task<int> WriteValuesAsync(StreamWriter writer, object values, str
109109
{
110110
cancellationToken.ThrowIfCancellationRequested();
111111

112-
#if NETSTANDARD2_0_OR_GREATER || NET
113112
IMiniExcelWriteAdapter writeAdapter = null;
114-
if (!MiniExcelWriteAdapterFactory.TryGetAsyncWriteAdapter(values, _configuration, out var asyncWriteAdapter))
113+
#if NETSTANDARD2_0_OR_GREATER || NET
114+
IAsyncMiniExcelWriteAdapter asyncWriteAdapter = null;
115+
#endif
116+
try
115117
{
116-
writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
117-
}
118-
var props = writeAdapter != null ? writeAdapter.GetColumns() : await asyncWriteAdapter.GetColumnsAsync();
118+
#if NETSTANDARD2_0_OR_GREATER || NET
119+
if (!MiniExcelWriteAdapterFactory.TryGetAsyncWriteAdapter(values, _configuration, out asyncWriteAdapter))
120+
{
121+
writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
122+
}
123+
124+
var props = writeAdapter != null
125+
? writeAdapter.GetColumns()
126+
: await asyncWriteAdapter.GetColumnsAsync();
119127
#else
120-
IMiniExcelWriteAdapter writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
128+
writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
121129
var props = writeAdapter.GetColumns();
122130
#endif
123-
if (props == null)
124-
{
125-
await _writer.WriteAsync(_configuration.NewLine);
126-
await _writer.FlushAsync();
127-
return 0;
128-
}
129-
130-
if (_printHeader)
131-
{
132-
await _writer.WriteAsync(GetHeader(props));
133-
await _writer.WriteAsync(newLine);
134-
}
135-
136-
var rowBuilder = new StringBuilder();
137-
var rowsWritten = 0;
138-
139-
if (writeAdapter != null)
140-
{
141-
foreach (var row in writeAdapter.GetRows(props, cancellationToken))
131+
if (props == null)
132+
{
133+
await _writer.WriteAsync(_configuration.NewLine);
134+
await _writer.FlushAsync();
135+
return 0;
136+
}
137+
138+
if (_printHeader)
142139
{
143-
rowBuilder.Clear();
144-
foreach (var column in row)
140+
await _writer.WriteAsync(GetHeader(props));
141+
await _writer.WriteAsync(newLine);
142+
}
143+
144+
var rowBuilder = new StringBuilder();
145+
var rowsWritten = 0;
146+
147+
if (writeAdapter != null)
148+
{
149+
foreach (var row in writeAdapter.GetRows(props, cancellationToken))
145150
{
146-
cancellationToken.ThrowIfCancellationRequested();
147-
AppendColumn(rowBuilder, column);
151+
rowBuilder.Clear();
152+
foreach (var column in row)
153+
{
154+
cancellationToken.ThrowIfCancellationRequested();
155+
AppendColumn(rowBuilder, column);
156+
}
157+
158+
RemoveTrailingSeparator(rowBuilder);
159+
await _writer.WriteAsync(rowBuilder.ToString());
160+
await _writer.WriteAsync(newLine);
161+
162+
rowsWritten++;
148163
}
149-
150-
RemoveTrailingSeparator(rowBuilder);
151-
await _writer.WriteAsync(rowBuilder.ToString());
152-
await _writer.WriteAsync(newLine);
153-
154-
rowsWritten++;
155164
}
156-
}
157165
#if NETSTANDARD2_0_OR_GREATER || NET
158-
else
159-
{
160-
await foreach (var row in asyncWriteAdapter.GetRowsAsync(props, cancellationToken))
166+
else
161167
{
162-
cancellationToken.ThrowIfCancellationRequested();
163-
rowBuilder.Clear();
164-
165-
await foreach (var column in row)
168+
await foreach (var row in asyncWriteAdapter.GetRowsAsync(props, cancellationToken))
166169
{
167170
cancellationToken.ThrowIfCancellationRequested();
168-
AppendColumn(rowBuilder, column);
171+
rowBuilder.Clear();
172+
173+
await foreach (var column in row)
174+
{
175+
cancellationToken.ThrowIfCancellationRequested();
176+
AppendColumn(rowBuilder, column);
177+
}
178+
179+
RemoveTrailingSeparator(rowBuilder);
180+
await _writer.WriteAsync(rowBuilder.ToString());
181+
await _writer.WriteAsync(newLine);
182+
183+
rowsWritten++;
169184
}
170-
171-
RemoveTrailingSeparator(rowBuilder);
172-
await _writer.WriteAsync(rowBuilder.ToString());
173-
await _writer.WriteAsync(newLine);
174-
175-
rowsWritten++;
176185
}
186+
#endif
187+
return rowsWritten;
177188
}
189+
finally
190+
{
191+
#if NETSTANDARD2_0_OR_GREATER || NET
192+
if (asyncWriteAdapter is IAsyncDisposable asyncDisposable)
193+
{
194+
await asyncDisposable.DisposeAsync().ConfigureAwait(false);
195+
}
178196
#endif
179-
return rowsWritten;
197+
}
180198
}
181199

182200
public async Task<int[]> SaveAsAsync(CancellationToken cancellationToken = default)

src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.Async.cs

Lines changed: 112 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -171,128 +171,152 @@ private static async Task WriteDimensionAsync(MiniExcelAsyncStreamWriter writer,
171171
private async Task<int> WriteValuesAsync(MiniExcelAsyncStreamWriter writer, object values, CancellationToken cancellationToken)
172172
{
173173
cancellationToken.ThrowIfCancellationRequested();
174-
175-
#if NETSTANDARD2_0_OR_GREATER || NET
174+
176175
IMiniExcelWriteAdapter writeAdapter = null;
177-
if (!MiniExcelWriteAdapterFactory.TryGetAsyncWriteAdapter(values, _configuration, out var asyncWriteAdapter))
176+
#if NETSTANDARD2_0_OR_GREATER || NET
177+
IAsyncMiniExcelWriteAdapter asyncWriteAdapter = null;
178+
#endif
179+
try
178180
{
179-
writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
180-
}
181+
#if NETSTANDARD2_0_OR_GREATER || NET
182+
if (!MiniExcelWriteAdapterFactory.TryGetAsyncWriteAdapter(values, _configuration, out asyncWriteAdapter))
183+
{
184+
writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
185+
}
181186

182-
var count = 0;
183-
var isKnownCount = writeAdapter != null && writeAdapter.TryGetKnownCount(out count);
184-
var props = writeAdapter != null ? writeAdapter?.GetColumns() : await asyncWriteAdapter.GetColumnsAsync();
187+
var count = 0;
188+
var isKnownCount = writeAdapter != null && writeAdapter.TryGetKnownCount(out count);
189+
var props = writeAdapter != null
190+
? writeAdapter?.GetColumns()
191+
: await asyncWriteAdapter.GetColumnsAsync();
185192
#else
186-
IMiniExcelWriteAdapter writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
193+
writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
187194

188-
var isKnownCount = writeAdapter.TryGetKnownCount(out var count);
189-
var props = writeAdapter.GetColumns();
195+
var isKnownCount = writeAdapter.TryGetKnownCount(out var count);
196+
var props = writeAdapter.GetColumns();
190197
#endif
191198

192-
if (props == null)
193-
{
194-
await WriteEmptySheetAsync(writer);
195-
return 0;
196-
}
197-
var maxColumnIndex = props.Count;
198-
int maxRowIndex;
199+
if (props == null)
200+
{
201+
await WriteEmptySheetAsync(writer);
202+
return 0;
203+
}
199204

200-
await writer.WriteAsync(WorksheetXml.StartWorksheetWithRelationship);
205+
var maxColumnIndex = props.Count;
206+
int maxRowIndex;
201207

202-
long dimensionPlaceholderPostition = 0;
208+
await writer.WriteAsync(WorksheetXml.StartWorksheetWithRelationship);
203209

204-
// We can write the dimensions directly if the row count is known
205-
if (_configuration.FastMode && !isKnownCount)
206-
{
207-
dimensionPlaceholderPostition = await WriteDimensionPlaceholderAsync(writer);
208-
}
209-
else if (isKnownCount)
210-
{
211-
maxRowIndex = count + (_printHeader ? 1 : 0);
212-
await writer.WriteAsync(WorksheetXml.Dimension(GetDimensionRef(maxRowIndex, props.Count)));
213-
}
210+
long dimensionPlaceholderPostition = 0;
214211

215-
//sheet view
216-
await writer.WriteAsync(GetSheetViews());
212+
// We can write the dimensions directly if the row count is known
213+
if (_configuration.FastMode && !isKnownCount)
214+
{
215+
dimensionPlaceholderPostition = await WriteDimensionPlaceholderAsync(writer);
216+
}
217+
else if (isKnownCount)
218+
{
219+
maxRowIndex = count + (_printHeader ? 1 : 0);
220+
await writer.WriteAsync(WorksheetXml.Dimension(GetDimensionRef(maxRowIndex, props.Count)));
221+
}
217222

218-
//cols:width
219-
ExcelWidthCollection widths = null;
220-
long columnWidthsPlaceholderPosition = 0;
221-
if (_configuration.EnableAutoWidth)
222-
{
223-
columnWidthsPlaceholderPosition = await WriteColumnWidthPlaceholdersAsync(writer, props);
224-
widths = new ExcelWidthCollection(_configuration.MinWidth, _configuration.MaxWidth, props);
225-
}
226-
else
227-
{
228-
await WriteColumnsWidthsAsync(writer, ExcelColumnWidth.FromProps(props), cancellationToken);
229-
}
223+
//sheet view
224+
await writer.WriteAsync(GetSheetViews());
230225

231-
//header
232-
await writer.WriteAsync(WorksheetXml.StartSheetData);
233-
var currentRowIndex = 0;
234-
if (_printHeader)
235-
{
236-
await PrintHeaderAsync(writer, props, cancellationToken);
237-
currentRowIndex++;
238-
}
226+
//cols:width
227+
ExcelWidthCollection widths = null;
228+
long columnWidthsPlaceholderPosition = 0;
229+
if (_configuration.EnableAutoWidth)
230+
{
231+
columnWidthsPlaceholderPosition = await WriteColumnWidthPlaceholdersAsync(writer, props);
232+
widths = new ExcelWidthCollection(_configuration.MinWidth, _configuration.MaxWidth, props);
233+
}
234+
else
235+
{
236+
await WriteColumnsWidthsAsync(writer, ExcelColumnWidth.FromProps(props), cancellationToken);
237+
}
239238

240-
if (writeAdapter != null)
241-
{
242-
foreach (var row in writeAdapter.GetRows(props, cancellationToken))
239+
//header
240+
await writer.WriteAsync(WorksheetXml.StartSheetData);
241+
var currentRowIndex = 0;
242+
if (_printHeader)
243243
{
244-
cancellationToken.ThrowIfCancellationRequested();
245-
246-
await writer.WriteAsync(WorksheetXml.StartRow(++currentRowIndex));
247-
foreach (var cellValue in row)
244+
await PrintHeaderAsync(writer, props, cancellationToken);
245+
currentRowIndex++;
246+
}
247+
248+
if (writeAdapter != null)
249+
{
250+
foreach (var row in writeAdapter.GetRows(props, cancellationToken))
248251
{
249252
cancellationToken.ThrowIfCancellationRequested();
250-
await WriteCellAsync(writer, currentRowIndex, cellValue.CellIndex, cellValue.Value, cellValue.Prop, widths);
253+
254+
await writer.WriteAsync(WorksheetXml.StartRow(++currentRowIndex));
255+
foreach (var cellValue in row)
256+
{
257+
cancellationToken.ThrowIfCancellationRequested();
258+
await WriteCellAsync(writer, currentRowIndex, cellValue.CellIndex, cellValue.Value,
259+
cellValue.Prop, widths);
260+
}
261+
262+
await writer.WriteAsync(WorksheetXml.EndRow);
251263
}
252-
await writer.WriteAsync(WorksheetXml.EndRow);
253264
}
254-
}
255265
#if NETSTANDARD2_0_OR_GREATER || NET
256-
else
257-
{
258-
await foreach (var row in asyncWriteAdapter.GetRowsAsync(props, cancellationToken))
266+
else
259267
{
260-
cancellationToken.ThrowIfCancellationRequested();
261-
await writer.WriteAsync(WorksheetXml.StartRow(++currentRowIndex));
262-
263-
await foreach (var cellValue in row)
268+
await foreach (var row in asyncWriteAdapter.GetRowsAsync(props, cancellationToken))
264269
{
265270
cancellationToken.ThrowIfCancellationRequested();
266-
await WriteCellAsync(writer, currentRowIndex, cellValue.CellIndex, cellValue.Value, cellValue.Prop, widths);
271+
await writer.WriteAsync(WorksheetXml.StartRow(++currentRowIndex));
272+
273+
await foreach (var cellValue in row)
274+
{
275+
cancellationToken.ThrowIfCancellationRequested();
276+
await WriteCellAsync(writer, currentRowIndex, cellValue.CellIndex, cellValue.Value,
277+
cellValue.Prop, widths);
278+
}
279+
280+
await writer.WriteAsync(WorksheetXml.EndRow);
267281
}
268-
await writer.WriteAsync(WorksheetXml.EndRow);
269282
}
270-
}
271283
#endif
272284

273-
maxRowIndex = currentRowIndex;
285+
maxRowIndex = currentRowIndex;
274286

275-
await writer.WriteAsync(WorksheetXml.Drawing(_currentSheetIndex));
276-
await writer.WriteAsync(WorksheetXml.EndSheetData);
287+
await writer.WriteAsync(WorksheetXml.Drawing(_currentSheetIndex));
288+
await writer.WriteAsync(WorksheetXml.EndSheetData);
277289

278-
if (_configuration.AutoFilter)
279-
{
280-
await writer.WriteAsync(WorksheetXml.Autofilter(GetDimensionRef(maxRowIndex, maxColumnIndex)));
281-
}
290+
if (_configuration.AutoFilter)
291+
{
292+
await writer.WriteAsync(WorksheetXml.Autofilter(GetDimensionRef(maxRowIndex, maxColumnIndex)));
293+
}
282294

283-
await writer.WriteAsync(WorksheetXml.EndWorksheet);
295+
await writer.WriteAsync(WorksheetXml.EndWorksheet);
284296

285-
if (_configuration.FastMode && dimensionPlaceholderPostition != 0)
286-
{
287-
await WriteDimensionAsync(writer, maxRowIndex, maxColumnIndex, dimensionPlaceholderPostition);
297+
if (_configuration.FastMode && dimensionPlaceholderPostition != 0)
298+
{
299+
await WriteDimensionAsync(writer, maxRowIndex, maxColumnIndex, dimensionPlaceholderPostition);
300+
}
301+
302+
if (_configuration.EnableAutoWidth)
303+
{
304+
await OverWriteColumnWidthPlaceholdersAsync(writer, columnWidthsPlaceholderPosition, widths.Columns,
305+
cancellationToken);
306+
}
307+
308+
var toSubtract = _printHeader ? 1 : 0;
309+
return maxRowIndex - toSubtract;
288310
}
289-
if (_configuration.EnableAutoWidth)
311+
finally
290312
{
291-
await OverWriteColumnWidthPlaceholdersAsync(writer, columnWidthsPlaceholderPosition, widths.Columns, cancellationToken);
313+
#if NETSTANDARD2_0_OR_GREATER || NET
314+
if (asyncWriteAdapter is IAsyncDisposable asyncDisposable)
315+
{
316+
await asyncDisposable.DisposeAsync().ConfigureAwait(false);
317+
}
318+
#endif
292319
}
293-
294-
var toSubtract = _printHeader ? 1 : 0;
295-
return maxRowIndex - toSubtract;
296320
}
297321

298322
private static async Task<long> WriteColumnWidthPlaceholdersAsync(MiniExcelAsyncStreamWriter writer, ICollection<ExcelColumnInfo> props)

0 commit comments

Comments
 (0)