Skip to content

Commit 2e9c310

Browse files
committed
[Optimization] SaveAs by datareader support dimension mini-software#231
1 parent b01e28c commit 2e9c310

9 files changed

Lines changed: 129 additions & 55 deletions

File tree

MiniExcel.sln

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ VisualStudioVersion = 17.0.31903.59
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiniExcelLibs", "src\MiniExcel\MiniExcelLibs.csproj", "{097903C9-1F81-4427-B4C8-530CB59687B8}"
77
EndProject
8-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2AFABF2E-D6C3-4983-B43A-76ADA2BB2876}"
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs and setting", "Docs and setting", "{2AFABF2E-D6C3-4983-B43A-76ADA2BB2876}"
99
ProjectSection(SolutionItems) = preProject
1010
.gitattributes = .gitattributes
1111
.gitignore = .gitignore
@@ -21,7 +21,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CC1E0601-AEC
2121
EndProject
2222
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{359A7094-3353-48F2-B3E1-FE9E59698318}"
2323
EndProject
24-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{3E370222-8E9E-45E8-8DCD-E5F41EE52A39}"
24+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Releases", "Releases", "{3E370222-8E9E-45E8-8DCD-E5F41EE52A39}"
2525
ProjectSection(SolutionItems) = preProject
2626
docs\README.md = docs\README.md
2727
docs\README.zh-CN.md = docs\README.zh-CN.md

docs/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,14 @@
2222

2323
---
2424

25+
26+
27+
### 1.27.0
28+
29+
- [Optimization] SaveAs by datareader support dimension #231 (via @shps951023)
30+
2531
### 1.26.7
32+
2633
- [OPT] Reduce memory allocation when using MemoryStream #427 (via @cupsos)
2734
- [OPT] Add System.Memory pacakge #427 (via @cupsos)
2835
- [OPT] Reduce memory allocation in GetImageFormat() #427 (via @cupsos)

docs/README.zh-CN.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,14 @@
2525

2626
---
2727

28+
29+
30+
### 1.27.0
31+
32+
- [Optimization] SaveAs by datareader 支持 dimension #231 (via @shps951023)
33+
2834
### 1.26.7
35+
2936
- [OPT] 减少 memory allocation 使用 MemoryStream #427 (via @cupsos)
3037
- [OPT] 添加 System.Memory pacakge #427 (via @cupsos)
3138
- [OPT] 减少 memory allocation in GetImageFormat() #427 (via @cupsos)

docs/README.zh-Hant.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@
2525
---
2626

2727

28+
29+
### 1.27.0
30+
31+
- [Optimization] SaveAs by datareader 支持 dimension #231 (via @shps951023)
32+
2833
### 1.26.7
34+
2935
- [OPT] 減少 memory allocation 使用 MemoryStream #427 (via @cupsos)
3036
- [OPT] 添加 System.Memory pacakge #427 (via @cupsos)
3137
- [OPT] 減少 memory allocation in GetImageFormat() #427 (via @cupsos)

src/MiniExcel/MiniExcelLibs.csproj

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>net45;netstandard2.0;net5.0</TargetFrameworks>
4-
<Version>1.26.7</Version>
4+
<Version>1.27.0</Version>
55
</PropertyGroup>
66
<PropertyGroup>
77
<AssemblyName>MiniExcel</AssemblyName>
88
<Title>MiniExcel</Title>
99
<Product>MiniExcel</Product>
1010
<PackageTags>excel;xlsx;csv;micro-helper;mini;openxml;helper;</PackageTags>
11-
<Description>Fast, Low-Memory, Easy Excel .NET helper to import/export/template spreadsheet
11+
<Description>
12+
Fast, Low-Memory, Easy Excel .NET helper to import/export/template spreadsheet
1213

13-
Github : https://github.com/shps951023/MiniExcel
14-
Gitee : https://gitee.com/dotnetchina/MiniExcel
15-
Issues : https://github.com/shps951023/MiniExcel/issues
16-
Todo : https://github.com/shps951023/MiniExcel/projects/1?fullscreen=true
17-
</Description>
14+
Github : https://github.com/MiniExcel/MiniExcel
15+
Gitee : https://gitee.com/dotnetchina/MiniExcel
16+
Issues : https://github.com/MiniExcel/MiniExcel/issues
17+
Todo : https://github.com/MiniExcel/MiniExcel/projects/1?fullscreen=true
18+
</Description>
1819
<Authors>LIN,WEI-HAN</Authors>
1920
<PackageId>MiniExcel</PackageId>
2021
<Copyright>LIN,WEI-HAN, 2021 onwards</Copyright>
2122
<NeutralLanguage>en</NeutralLanguage>
22-
<license>https://raw.githubusercontent.com/shps951023/MiniExcel/master/LICENSE</license>
23+
<license>https://raw.githubusercontent.com/MiniExcel/MiniExcel/master/LICENSE</license>
2324
<RootNamespace>MiniExcelLibs</RootNamespace>
2425
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
25-
<PackageProjectUrl>https://github.com/shps951023/MiniExcel</PackageProjectUrl>
26-
<RepositoryUrl>https://github.com/shps951023/MiniExcel</RepositoryUrl>
26+
<PackageProjectUrl>https://github.com/MiniExcel/MiniExcel</PackageProjectUrl>
27+
<RepositoryUrl>https://github.com/MiniExcel/MiniExcel</RepositoryUrl>
2728
<PackageIcon>icon.png</PackageIcon>
28-
<PackageReleaseNotes>Please Check [Release Notes](https://github.com/shps951023/MiniExcel/tree/master/docs)</PackageReleaseNotes>
29+
<PackageReleaseNotes>Please Check [Release Notes](https://github.com/MiniExcel/MiniExcel/tree/master/docs)</PackageReleaseNotes>
2930
<RepositoryType>Github</RepositoryType>
3031
</PropertyGroup>
3132
<ItemGroup Condition=" '$(TargetFramework)' == 'net461'">
@@ -35,14 +36,14 @@ Todo : https://github.com/shps951023/MiniExcel/projects/1?fullscreen=true
3536
<Reference Include="System.IO.Compression" />
3637
</ItemGroup>
3738
<ItemGroup>
38-
<None Update="icon.png">
39-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
40-
</None>
39+
<None Update="icon.png">
40+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
41+
</None>
42+
</ItemGroup>
43+
<ItemGroup>
44+
<None Include="icon.png" Pack="true" PackagePath="\" />
45+
</ItemGroup>
46+
<ItemGroup Condition="'$(TargetFramework)' == 'net45' Or '$(TargetFramework)' == 'netstandard2.0'">
47+
<PackageReference Include="System.Memory" Version="4.5.5" />
4148
</ItemGroup>
42-
<ItemGroup>
43-
<None Include="icon.png" Pack="true" PackagePath="\" />
44-
</ItemGroup>
45-
<ItemGroup Condition="'$(TargetFramework)' == 'net45' Or '$(TargetFramework)' == 'netstandard2.0'">
46-
<PackageReference Include="System.Memory" Version="4.5.5" />
47-
</ItemGroup>
4849
</Project>

src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ internal partial class ExcelOpenXmlSheetWriter : IExcelWriter
5454
public ExcelOpenXmlSheetWriter(Stream stream, object value, string sheetName, IConfiguration configuration, bool printHeader)
5555
{
5656
this._stream = stream;
57-
this._archive = new MiniExcelZipArchive(_stream, ZipArchiveMode.Create, true, _utf8WithBom);
57+
// Why ZipArchiveMode.Update not ZipArchiveMode.Create?
58+
// R : Mode create - ZipArchiveEntry does not support seeking.'
59+
this._archive = new MiniExcelZipArchive(_stream, ZipArchiveMode.Update, true, _utf8WithBom);
5860
this._configuration = configuration as OpenXmlConfiguration ?? OpenXmlConfiguration.DefaultConfig;
5961
this._printHeader = printHeader;
6062
this._value = value;
@@ -579,15 +581,13 @@ private void GenerateSheetByDataTable(MiniExcelStreamWriter writer, DataTable va
579581
private void GenerateSheetByIDataReader(MiniExcelStreamWriter writer, IDataReader reader)
580582
{
581583
var xy = ExcelOpenXmlUtils.ConvertCellToXY("A1"); /*TODO:code smell*/
582-
584+
long dimensionWritePosition = 0;
583585
writer.Write($@"<?xml version=""1.0"" encoding=""utf-8""?><x:worksheet xmlns:x=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"">");
584586
var yIndex = xy.Item2;
585587
var xIndex = 0;
586588
{
587-
// TODO: dimension
588-
//var maxRowIndex = value.Rows.Count + (printHeader && value.Rows.Count > 0 ? 1 : 0);
589-
//var maxColumnIndex = value.Columns.Count;
590-
//writer.Write($@"<x:dimension ref=""{GetDimensionRef(maxRowIndex, maxColumnIndex)}""/>");
589+
dimensionWritePosition = writer.WriteAndFlush($@"<x:dimension ref=""");
590+
writer.Write($@" />"); // end of code will be replaced
591591
writer.Write("<x:sheetData>");
592592
int fieldCount = reader.FieldCount;
593593
if (_printHeader)
@@ -623,7 +623,10 @@ private void GenerateSheetByIDataReader(MiniExcelStreamWriter writer, IDataReade
623623
writer.Write("</x:sheetData>");
624624
if (_configuration.AutoFilter)
625625
writer.Write($"<x:autoFilter ref=\"A1:{ExcelOpenXmlUtils.ConvertXyToCell((xIndex-1)/*TODO:code smell*/, yIndex-1)}\" />");
626-
writer.Write("</x:worksheet>");
626+
writer.WriteAndFlush("</x:worksheet>");
627+
628+
writer.SetPosition(dimensionWritePosition);
629+
writer.WriteAndFlush($@"A1:{ExcelOpenXmlUtils.ConvertXyToCell((xIndex - 1)/*TODO:code smell*/, yIndex - 1)}""");
627630
}
628631
629632
private static void WriteC(MiniExcelStreamWriter writer, string r, string columnName)

src/MiniExcel/OpenXml/MiniExcelStreamWriter.cs

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,42 @@ internal class MiniExcelStreamWriter : IDisposable
88
{
99
private readonly Stream _stream;
1010
private readonly Encoding _encoding;
11-
private readonly StreamWriter _streamWriter;
11+
internal readonly StreamWriter _streamWriter;
1212
private bool disposedValue;
13-
//private byte[] _cacheValueBytes;
14-
1513
public MiniExcelStreamWriter(Stream stream,Encoding encoding, int bufferSize)
1614
{
1715
this._stream = stream;
1816
this._encoding = encoding;
1917
this._streamWriter = new StreamWriter(stream, this._encoding, bufferSize);
2018
}
21-
public void Write(string content,bool flushImmediately=false)
19+
public void Write(string content)
2220
{
2321
if (string.IsNullOrEmpty(content))
2422
return;
25-
//if (flushImmediately)
26-
//else
27-
//_cacheValueBytes.CopyTo
28-
//TODO:
29-
//var bytes = this._encoding.GetBytes(content);
30-
//this._stream.Write(bytes, 0, bytes.Length);
31-
3223
this._streamWriter.Write(content);
3324
}
3425

26+
public long WriteAndFlush(string content)
27+
{
28+
this.Write(content);
29+
this._streamWriter.Flush();
30+
return this._streamWriter.BaseStream.Position;
31+
}
32+
33+
public void SetPosition(long position)
34+
{
35+
this._streamWriter.BaseStream.Position = position;
36+
}
37+
3538
protected virtual void Dispose(bool disposing)
3639
{
3740
if (!disposedValue)
3841
{
39-
if (disposing)
40-
{
41-
// TODO: dispose managed state (managed objects)
42-
}
43-
44-
// free unmanaged resources (unmanaged objects) and override finalizer
45-
this._streamWriter?.Dispose();
46-
// TODO: set large fields to null
42+
this._streamWriter?.Dispose();
4743
disposedValue = true;
4844
}
4945
}
5046

51-
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
52-
// ~MiniExcelStreamWriter()
53-
// {
54-
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
55-
// Dispose(disposing: false);
56-
// }
57-
5847
public void Dispose()
5948
{
6049
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<Query Kind="Program">
2+
<NuGetReference>MiniExcel</NuGetReference>
3+
<Namespace>MiniExcelLibs</Namespace>
4+
</Query>
5+
6+
void Main()
7+
{
8+
ConsoleApplication.Program.Main(null);
9+
}
10+
11+
// You can define other methods, fields, classes and namespaces here
12+
13+
14+
namespace ConsoleApplication
15+
{
16+
using System;
17+
using System.IO;
18+
using System.IO.Compression;
19+
public class Program
20+
{
21+
public static void Main(string[] args)
22+
{
23+
var path = Path.GetTempPath() + Guid.NewGuid() + ".zip";
24+
Console.WriteLine(path);
25+
using (FileStream zipToOpen = new FileStream(path, FileMode.Create))
26+
{
27+
using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
28+
{
29+
ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
30+
using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
31+
{
32+
writer.WriteLine("Information about this package.");
33+
writer.Flush();
34+
writer.BaseStream.Position=0;
35+
writer.WriteLine("========================");
36+
}
37+
}
38+
}
39+
}
40+
}
41+
}

tests/MiniExcelTests/MiniExcelIssueTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,26 @@ public MiniExcelIssueTests(ITestOutputHelper output)
3434
this.output = output;
3535
}
3636

37+
[Fact]
38+
public void TestIssue_DataReaderSupportDimension()
39+
{
40+
{
41+
DataTable table = new DataTable();
42+
{
43+
table.Columns.Add("id", typeof(int));
44+
table.Columns.Add("name", typeof(string));
45+
table.Rows.Add(1, "Jack");
46+
table.Rows.Add(2, "Mike");
47+
}
48+
var path = Path.GetTempPath() + Guid.NewGuid() + ".xlsx";
49+
DataTableReader reader = table.CreateDataReader();
50+
MiniExcel.SaveAs(path, reader);
51+
var xml = Helpers.GetZipFileContent(path, "xl/worksheets/sheet1.xml");
52+
Assert.Contains("<x:autoFilter ref=\"A1:B3\" />", xml);
53+
Assert.Contains("<x:dimension ref=\"A1:B3\" />", xml);
54+
}
55+
}
56+
3757
/// <summary>
3858
/// [ · Issue #413 · MiniExcel/MiniExcel]
3959
/// (https://github.com/MiniExcel/MiniExcel/issues/413)

0 commit comments

Comments
 (0)