Skip to content

Commit

Permalink
Implement autowidth for sync write
Browse files Browse the repository at this point in the history
  • Loading branch information
Discolai committed Nov 15, 2024
1 parent f3cb303 commit f24c90a
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 12 deletions.
90 changes: 78 additions & 12 deletions src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MiniExcelLibs.OpenXml
{
Expand Down Expand Up @@ -141,6 +142,8 @@ private void GenerateSheetByIDataReader(MiniExcelStreamWriter writer, IDataReade
var yIndex = 1;
int maxColumnIndex;
int maxRowIndex;
ExcelWidthCollection widths = null;
long columnWidthsPlaceholderPosition = 0;
{
if (_configuration.FastMode)
{
Expand All @@ -159,7 +162,15 @@ private void GenerateSheetByIDataReader(MiniExcelStreamWriter writer, IDataReade
//sheet view
writer.Write(GetSheetViews());

WriteColumnsWidths(writer, ExcelColumnWidth.FromProps(props));
if (_configuration.EnableAutoWidth)
{
columnWidthsPlaceholderPosition = WriteColumnWidthPlaceholders(writer, props);
widths = new ExcelWidthCollection(_configuration.MinWidth, _configuration.MaxWidth, props);
}
else
{
WriteColumnsWidths(writer, ExcelColumnWidth.FromProps(props));
}

writer.Write(WorksheetXml.StartSheetData);
int fieldCount = reader.FieldCount;
Expand All @@ -179,7 +190,7 @@ private void GenerateSheetByIDataReader(MiniExcelStreamWriter writer, IDataReade
for (int i = 0; i < fieldCount; i++)
{
var cellValue = reader.GetValue(i);
WriteCell(writer, yIndex, xIndex, cellValue, columnInfo: props?.FirstOrDefault(x => x?.ExcelColumnIndex == xIndex - 1));
WriteCell(writer, yIndex, xIndex, cellValue, columnInfo: props?.FirstOrDefault(x => x?.ExcelColumnIndex == xIndex - 1), widths);
xIndex++;
}
writer.Write(WorksheetXml.EndRow);
Expand All @@ -202,6 +213,12 @@ private void GenerateSheetByIDataReader(MiniExcelStreamWriter writer, IDataReade
{
WriteDimension(writer, maxRowIndex, maxColumnIndex, dimensionPlaceholderPosition);
}

if (_configuration.EnableAutoWidth)
{
OverWriteColumnWidthPlaceholders(writer, columnWidthsPlaceholderPosition, widths.Columns);
}

}

private void GenerateSheetByEnumerable(MiniExcelStreamWriter writer, IEnumerable values)
Expand Down Expand Up @@ -287,7 +304,17 @@ private void GenerateSheetByEnumerable(MiniExcelStreamWriter writer, IEnumerable
writer.Write(GetSheetViews());

//cols:width
WriteColumnsWidths(writer, ExcelColumnWidth.FromProps(props));
ExcelWidthCollection widths = null;
long columnWidthsPlaceholderPosition = 0;
if (_configuration.EnableAutoWidth)
{
columnWidthsPlaceholderPosition = WriteColumnWidthPlaceholders(writer, props);
widths = new ExcelWidthCollection(_configuration.MinWidth, _configuration.MaxWidth, props);
}
else
{
WriteColumnsWidths(writer, ExcelColumnWidth.FromProps(props));
}

//header
writer.Write(WorksheetXml.StartSheetData);
Expand All @@ -305,13 +332,13 @@ private void GenerateSheetByEnumerable(MiniExcelStreamWriter writer, IEnumerable
switch (mode)
{
case "IDictionary<string, object>": //Dapper Row
maxRowIndex = GenerateSheetByColumnInfo<IDictionary<string, object>>(writer, enumerator, props, xIndex, yIndex);
maxRowIndex = GenerateSheetByColumnInfo<IDictionary<string, object>>(writer, enumerator, props, widths, xIndex, yIndex);
break;
case "IDictionary":
maxRowIndex = GenerateSheetByColumnInfo<IDictionary>(writer, enumerator, props, xIndex, yIndex);
maxRowIndex = GenerateSheetByColumnInfo<IDictionary>(writer, enumerator, props, widths, xIndex, yIndex);
break;
case "Properties":
maxRowIndex = GenerateSheetByColumnInfo<object>(writer, enumerator, props, xIndex, yIndex);
maxRowIndex = GenerateSheetByColumnInfo<object>(writer, enumerator, props, widths, xIndex, yIndex);
break;
default:
throw new NotImplementedException($"Type {values.GetType().FullName} is not implemented. Please open an issue.");
Expand All @@ -332,6 +359,11 @@ private void GenerateSheetByEnumerable(MiniExcelStreamWriter writer, IEnumerable
{
WriteDimension(writer, maxRowIndex, maxColumnIndex, dimensionPlaceholderPostition);
}

if (_configuration.EnableAutoWidth)
{
OverWriteColumnWidthPlaceholders(writer, columnWidthsPlaceholderPosition, widths.Columns);
}
}

private void GenerateSheetByDataTable(MiniExcelStreamWriter writer, DataTable value)
Expand Down Expand Up @@ -359,7 +391,17 @@ private void GenerateSheetByDataTable(MiniExcelStreamWriter writer, DataTable va
//sheet view
writer.Write(GetSheetViews());

WriteColumnsWidths(writer, ExcelColumnWidth.FromProps(props));
ExcelWidthCollection widths = null;
long columnWidthsPlaceholderPosition = 0;
if (_configuration.EnableAutoWidth)
{
columnWidthsPlaceholderPosition = WriteColumnWidthPlaceholders(writer, props);
widths = new ExcelWidthCollection(_configuration.MinWidth, _configuration.MaxWidth, props);
}
else
{
WriteColumnsWidths(writer, ExcelColumnWidth.FromProps(props));
}

writer.Write(WorksheetXml.StartSheetData);
if (_printHeader)
Expand All @@ -385,7 +427,7 @@ private void GenerateSheetByDataTable(MiniExcelStreamWriter writer, DataTable va
for (int j = 0; j < value.Columns.Count; j++)
{
var cellValue = value.Rows[i][j];
WriteCell(writer, yIndex, xIndex, cellValue, columnInfo: props?.FirstOrDefault(x => x?.ExcelColumnIndex == xIndex - 1));
WriteCell(writer, yIndex, xIndex, cellValue, columnInfo: props?.FirstOrDefault(x => x?.ExcelColumnIndex == xIndex - 1), widths);
xIndex++;
}
writer.Write(WorksheetXml.EndRow);
Expand All @@ -399,10 +441,33 @@ private void GenerateSheetByDataTable(MiniExcelStreamWriter writer, DataTable va
writer.Write(WorksheetXml.Autofilter(GetDimensionRef(maxRowIndex, maxColumnIndex)));
}

if (_configuration.EnableAutoWidth)
{
OverWriteColumnWidthPlaceholders(writer, columnWidthsPlaceholderPosition, widths.Columns);
}

writer.Write(WorksheetXml.EndWorksheet);
}

private static void WriteColumnsWidths(MiniExcelStreamWriter writer, IEnumerable<ExcelColumnWidth> columnWidths)
private long WriteColumnWidthPlaceholders(MiniExcelStreamWriter writer, ICollection<ExcelColumnInfo> props)
{
var placeholderPosition = writer.Flush();
writer.WriteWhitespace(WorksheetXml.GetColumnPlaceholderLength(props.Count));
return placeholderPosition;
}

private void OverWriteColumnWidthPlaceholders(MiniExcelStreamWriter writer, long placeholderPosition, IEnumerable<ExcelColumnWidth> columnWidths)
{
var position = writer.Flush();

writer.SetPosition(placeholderPosition);
WriteColumnsWidths(writer, columnWidths);

writer.Flush();
writer.SetPosition(position);
}

private void WriteColumnsWidths(MiniExcelStreamWriter writer, IEnumerable<ExcelColumnWidth> columnWidths)
{
var hasWrittenStart = false;
foreach (var column in columnWidths)
Expand Down Expand Up @@ -443,7 +508,7 @@ private static void PrintHeader(MiniExcelStreamWriter writer, List<ExcelColumnIn
writer.Write(WorksheetXml.EndRow);
}

private int GenerateSheetByColumnInfo<T>(MiniExcelStreamWriter writer, IEnumerator value, List<ExcelColumnInfo> props, int xIndex = 1, int yIndex = 1)
private int GenerateSheetByColumnInfo<T>(MiniExcelStreamWriter writer, IEnumerator value, List<ExcelColumnInfo> props, ExcelWidthCollection widthCollection, int xIndex = 1, int yIndex = 1)
{
var isDic = typeof(T) == typeof(IDictionary);
var isDapperRow = typeof(T) == typeof(IDictionary<string, object>);
Expand Down Expand Up @@ -477,7 +542,7 @@ private int GenerateSheetByColumnInfo<T>(MiniExcelStreamWriter writer, IEnumerat
cellValue = columnInfo.Property.GetValue(v);
}

WriteCell(writer, yIndex, cellIndex, cellValue, columnInfo);
WriteCell(writer, yIndex, cellIndex, cellValue, columnInfo, widthCollection);

cellIndex++;
}
Expand All @@ -489,7 +554,7 @@ private int GenerateSheetByColumnInfo<T>(MiniExcelStreamWriter writer, IEnumerat
return yIndex - 1;
}

private void WriteCell(MiniExcelStreamWriter writer, int rowIndex, int cellIndex, object value, ExcelColumnInfo columnInfo)
private void WriteCell(MiniExcelStreamWriter writer, int rowIndex, int cellIndex, object value, ExcelColumnInfo columnInfo, ExcelWidthCollection widthCollection)
{
var columnReference = ExcelOpenXmlUtils.ConvertXyToCell(cellIndex, rowIndex);
var valueIsNull = value is null || value is DBNull;
Expand All @@ -510,6 +575,7 @@ private void WriteCell(MiniExcelStreamWriter writer, int rowIndex, int cellIndex
/*Prefix and suffix blank space will lost after SaveAs #294*/
var preserveSpace = cellValue != null && (cellValue.StartsWith(" ", StringComparison.Ordinal) || cellValue.EndsWith(" ", StringComparison.Ordinal));
writer.Write(WorksheetXml.Cell(columnReference, dataType, styleIndex, cellValue, preserveSpace: preserveSpace, columnType: columnType));
widthCollection?.AdjustWidth(cellIndex, cellValue);
}

private static void WriteCell(MiniExcelStreamWriter writer, string cellReference, string columnName)
Expand Down
5 changes: 5 additions & 0 deletions src/MiniExcel/OpenXml/MiniExcelStreamWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public long WriteAndFlush(string content)
return this._streamWriter.BaseStream.Position;
}

public void WriteWhitespace(int length)
{
_streamWriter.Write(new string(' ', length));
}

public long Flush()
{
this._streamWriter.Flush();
Expand Down

0 comments on commit f24c90a

Please sign in to comment.