Skip to content

Commit ead2149

Browse files
Fixes issue #905 on the maintenance branch
Co-Authored-By: Amos <hzh990094740@outlook.com>
1 parent b20a5fd commit ead2149

File tree

5 files changed

+214
-163
lines changed

5 files changed

+214
-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: 70 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -109,74 +109,93 @@ 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,
120+
out asyncWriteAdapter))
121+
{
122+
writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
123+
}
124+
125+
var props = writeAdapter != null
126+
? writeAdapter.GetColumns()
127+
: await asyncWriteAdapter.GetColumnsAsync();
119128
#else
120-
IMiniExcelWriteAdapter writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
129+
writeAdapter = MiniExcelWriteAdapterFactory.GetWriteAdapter(values, _configuration);
121130
var props = writeAdapter.GetColumns();
122131
#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))
132+
if (props == null)
133+
{
134+
await _writer.WriteAsync(_configuration.NewLine);
135+
await _writer.FlushAsync();
136+
return 0;
137+
}
138+
139+
if (_printHeader)
142140
{
143-
rowBuilder.Clear();
144-
foreach (var column in row)
141+
await _writer.WriteAsync(GetHeader(props));
142+
await _writer.WriteAsync(newLine);
143+
}
144+
145+
var rowBuilder = new StringBuilder();
146+
var rowsWritten = 0;
147+
148+
if (writeAdapter != null)
149+
{
150+
foreach (var row in writeAdapter.GetRows(props, cancellationToken))
145151
{
146-
cancellationToken.ThrowIfCancellationRequested();
147-
AppendColumn(rowBuilder, column);
152+
rowBuilder.Clear();
153+
foreach (var column in row)
154+
{
155+
cancellationToken.ThrowIfCancellationRequested();
156+
AppendColumn(rowBuilder, column);
157+
}
158+
159+
RemoveTrailingSeparator(rowBuilder);
160+
await _writer.WriteAsync(rowBuilder.ToString());
161+
await _writer.WriteAsync(newLine);
162+
163+
rowsWritten++;
148164
}
149-
150-
RemoveTrailingSeparator(rowBuilder);
151-
await _writer.WriteAsync(rowBuilder.ToString());
152-
await _writer.WriteAsync(newLine);
153-
154-
rowsWritten++;
155165
}
156-
}
157166
#if NETSTANDARD2_0_OR_GREATER || NET
158-
else
159-
{
160-
await foreach (var row in asyncWriteAdapter.GetRowsAsync(props, cancellationToken))
167+
else
161168
{
162-
cancellationToken.ThrowIfCancellationRequested();
163-
rowBuilder.Clear();
164-
165-
await foreach (var column in row)
169+
await foreach (var row in asyncWriteAdapter.GetRowsAsync(props, cancellationToken))
166170
{
167171
cancellationToken.ThrowIfCancellationRequested();
168-
AppendColumn(rowBuilder, column);
172+
rowBuilder.Clear();
173+
174+
await foreach (var column in row)
175+
{
176+
cancellationToken.ThrowIfCancellationRequested();
177+
AppendColumn(rowBuilder, column);
178+
}
179+
180+
RemoveTrailingSeparator(rowBuilder);
181+
await _writer.WriteAsync(rowBuilder.ToString());
182+
await _writer.WriteAsync(newLine);
183+
184+
rowsWritten++;
169185
}
170-
171-
RemoveTrailingSeparator(rowBuilder);
172-
await _writer.WriteAsync(rowBuilder.ToString());
173-
await _writer.WriteAsync(newLine);
174-
175-
rowsWritten++;
176186
}
187+
#endif
188+
return rowsWritten;
177189
}
190+
finally
191+
{
192+
#if NETSTANDARD2_0_OR_GREATER || NET
193+
if (asyncWriteAdapter is IAsyncDisposable asyncDisposable)
194+
{
195+
await asyncDisposable.DisposeAsync().ConfigureAwait(false);
196+
}
178197
#endif
179-
return rowsWritten;
198+
}
180199
}
181200

182201
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)