diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/IXLCell.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/IXLCell.cs
index 7a49d70..7b35775 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/IXLCell.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/IXLCell.cs
@@ -170,6 +170,8 @@
/// The comments for the named range.
IXLCell AddToNamed(String rangeName, XLScope scope, String comment);
- IXLCell CopyFrom(IXLCell otherCell);
+ //IXLCell CopyFrom(IXLCell otherCell);
+
+ void CopyTo(IXLCell target);
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs
index 7e785a1..17892f9 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs
@@ -280,6 +280,13 @@
private Boolean SetRange(Object rangeObject)
{
var asRange = rangeObject as XLRangeBase;
+ if (asRange == null)
+ {
+ var tmp = rangeObject as XLCell;
+ if (tmp != null)
+ asRange = tmp.AsRange() as XLRangeBase;
+ }
+
if (asRange != null)
{
Int32 maxRows;
@@ -307,8 +314,8 @@
{
var sourceCell = (XLCell)asRange.Cell(ro, co);
var targetCell = (XLCell)worksheet.Cell(Address.RowNumber + ro - 1, Address.ColumnNumber + co - 1);
- targetCell.CopyValues(sourceCell);
- targetCell.Style = sourceCell.style;
+ targetCell.CopyFrom(sourceCell);
+ //targetCell.Style = sourceCell.style;
}
}
var rangesToMerge = new List();
@@ -1538,5 +1545,10 @@
return retVal;
}
}
+
+ public void CopyTo(IXLCell target)
+ {
+ target.Value = this;
+ }
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumn.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumn.cs
index 81fabc8..fc595b0 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumn.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumn.cs
@@ -149,5 +149,11 @@
void Expand();
Int32 CellCount();
+
+ void CopyTo(IXLCell target);
+ void CopyTo(IXLRangeBase target);
+
+ void SetAutoFilter();
+ void SetAutoFilter(Boolean autoFilter);
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs
index c2e1743..795c421 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs
@@ -267,5 +267,7 @@
IXLSheetProtection Protect(String password);
IXLSheetProtection Unprotect();
IXLSheetProtection Unprotect(String password);
+
+ IXLRangeBase AutoFilterRange { get; set; }
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRange.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRange.cs
index e509c5c..26fae12 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRange.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRange.cs
@@ -217,6 +217,12 @@
IXLRange RangeUsed();
IXLRange SortBy(String columns);
+
+ void CopyTo(IXLCell target);
+ void CopyTo(IXLRangeBase target);
+
+ void SetAutoFilter();
+ void SetAutoFilter(Boolean autoFilter);
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeColumn.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeColumn.cs
index c7701ce..acb0046 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeColumn.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeColumn.cs
@@ -77,6 +77,12 @@
String ColumnLetter();
Int32 CellCount();
+
+ void CopyTo(IXLCell target);
+ void CopyTo(IXLRangeBase target);
+
+ void SetAutoFilter();
+ void SetAutoFilter(Boolean autoFilter);
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeRow.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeRow.cs
index 8bb3055..12d284c 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeRow.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeRow.cs
@@ -84,6 +84,12 @@
Int32 RowNumber();
Int32 CellCount();
+
+ void CopyTo(IXLCell target);
+ void CopyTo(IXLRangeBase target);
+
+ void SetAutoFilter();
+ void SetAutoFilter(Boolean autoFilter);
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs
index cd33077..7f060e7 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs
@@ -1017,5 +1017,28 @@
return retVal;
}
}
+
+ public void CopyTo(IXLRangeBase target)
+ {
+ CopyTo(target.FirstCell());
+ }
+
+ public void CopyTo(IXLCell target)
+ {
+ target.Value = this;
+ }
+
+ public void SetAutoFilter()
+ {
+ SetAutoFilter(true);
+ }
+
+ public void SetAutoFilter(Boolean autoFilter)
+ {
+ if (autoFilter)
+ Worksheet.AutoFilterRange = this;
+ else
+ Worksheet.AutoFilterRange = null;
+ }
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRow.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRow.cs
index 7e1b2df..243907a 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRow.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRow.cs
@@ -149,5 +149,11 @@
void Expand();
Int32 CellCount();
+
+ void CopyTo(IXLCell target);
+ void CopyTo(IXLRangeBase target);
+
+ void SetAutoFilter();
+ void SetAutoFilter(Boolean autoFilter);
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Tables/IXLTable.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Tables/IXLTable.cs
index a00f8d6..8c8a767 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/Tables/IXLTable.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Tables/IXLTable.cs
@@ -121,5 +121,8 @@
///
/// The rows to return.
new IXLTableRows Rows(string rows);
+
+ void CopyTo(IXLCell target);
+ void CopyTo(IXLRangeBase target);
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook.cs
index abe6bb5..b50a15a 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook.cs
@@ -73,6 +73,7 @@
}
private String originalFile;
+ private Stream originalStream;
///
/// Opens an existing workbook from a file.
///
@@ -92,6 +93,7 @@
: this()
{
loadSource = XLLoadSource.Stream;
+ originalStream = stream;
Load(stream);
}
@@ -131,9 +133,9 @@
public void Save()
{
if (loadSource == XLLoadSource.New)
- throw new Exception("This is a new file, please use one of the SaveAs method.");
+ throw new Exception("This is a new file, please use one of the SaveAs methods.");
else if (loadSource == XLLoadSource.Stream)
- throw new Exception("The file was loaded from a stream, please use one of the SaveAs method.");
+ CreatePackage(originalStream, false);
else
CreatePackage(originalFile);
}
@@ -142,21 +144,72 @@
///
public void SaveAs(String file)
{
- if (originalFile == null)
- File.Delete(file);
- else if (originalFile.Trim().ToLower() != file.Trim().ToLower())
- File.Copy(originalFile, file, true);
+ if (loadSource == XLLoadSource.New)
+ {
+ if (File.Exists(file))
+ File.Delete(file);
- CreatePackage(file);
+ CreatePackage(file);
+ }
+ else if (loadSource == XLLoadSource.File)
+ {
+ if (originalFile.Trim().ToLower() != file.Trim().ToLower())
+ File.Copy(originalFile, file, true);
+
+ CreatePackage(file);
+ }
+ else if (loadSource == XLLoadSource.Stream)
+ {
+ originalStream.Position = 0;
+
+ using (var fileStream = File.Create(file))
+ {
+ CopyStream(originalStream, fileStream);
+ //fileStream.Position = 0;
+ CreatePackage(fileStream, false);
+ fileStream.Close();
+ }
+ }
}
///
/// Saves the current workbook to a stream.
///
public void SaveAs(Stream stream)
{
- CreatePackage(stream);
+ if (loadSource == XLLoadSource.New)
+ {
+ CreatePackage(stream, true);
+ }
+ else if (loadSource == XLLoadSource.File)
+ {
+ using (var fileStream = new FileStream(originalFile, FileMode.Open))
+ {
+ CopyStream(fileStream, stream);
+ fileStream.Close();
+ }
+ CreatePackage(stream, false);
+ }
+ else if (loadSource == XLLoadSource.Stream)
+ {
+ originalStream.Position = 0;
+ if (originalStream != stream)
+ CopyStream(originalStream, stream);
+
+ CreatePackage(stream, false);
+ }
}
+ internal void CopyStream(Stream input, Stream output)
+ {
+ byte[] buffer = new byte[8 * 1024];
+ int len;
+ while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ output.Write(buffer, 0, len);
+ }
+ }
+
+
///
/// Gets or sets the default style for the workbook.
/// All new worksheets will use this style.
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs
index 0c3e486..9390c89 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs
@@ -390,6 +390,8 @@
}
#endregion
+ LoadAutoFilter(worksheetPart, ws);
+
LoadSheetProtection(worksheetPart, ws);
LoadDataValidations(worksheetPart, ws);
@@ -481,6 +483,16 @@
return XLCellValues.Text;
}
+ private void LoadAutoFilter(WorksheetPart worksheetPart, XLWorksheet ws)
+ {
+ var autoFilterQuery = worksheetPart.Worksheet.Descendants();
+ if (autoFilterQuery.Count() > 0)
+ {
+ var af = (AutoFilter)autoFilterQuery.First();
+ ws.Range(af.Reference.Value).SetAutoFilter();
+ }
+ }
+
private void LoadSheetProtection(WorksheetPart worksheetPart, XLWorksheet ws)
{
var sheetProtectionQuery = worksheetPart.Worksheet.Descendants();
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs
index fd89dbd..0a5250e 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs
@@ -332,9 +332,14 @@
}
}
- private void CreatePackage(Stream stream)
+ private void CreatePackage(Stream stream, Boolean newStream)
{
- SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
+ SpreadsheetDocument package;
+ if (newStream)
+ package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
+ else
+ package = SpreadsheetDocument.Open(stream, true);
+
using (package)
{
CreateParts(package);
@@ -2070,6 +2075,27 @@
}
#endregion
+ #region AutoFilter
+ if (xlWorksheet.AutoFilterRange != null)
+ {
+ if (worksheetPart.Worksheet.Elements().Count() == 0)
+ {
+ OpenXmlElement previousElement = cm.GetPreviousElementFor(XLWSContentManager.XLWSContents.AutoFilter);
+ worksheetPart.Worksheet.InsertAfter(new AutoFilter(), previousElement);
+ }
+
+ var autoFilter = worksheetPart.Worksheet.Elements().First();
+ cm.SetElement(XLWSContentManager.XLWSContents.AutoFilter, autoFilter);
+
+ autoFilter.Reference = xlWorksheet.AutoFilterRange.RangeAddress.ToString();
+ }
+ else
+ {
+ worksheetPart.Worksheet.RemoveAllChildren();
+ cm.SetElement(XLWSContentManager.XLWSContents.AutoFilter, null);
+ }
+ #endregion
+
#region MergeCells
MergeCells mergeCells = null;
if (xlWorksheet.Internals.MergedRanges.Count() > 0)
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs
index 6ff35f2..d687029 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs
@@ -602,6 +602,9 @@
}
}
+ if (this.AutoFilterRange != null)
+ ws.Range(this.AutoFilterRange.RangeAddress).SetAutoFilter();
+
return ws;
}
@@ -699,6 +702,7 @@
{
return Protection.Unprotect(password);
}
-
+
+ public IXLRangeBase AutoFilterRange { get; set; }
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML_Examples/ClosedXML_Examples.csproj b/ClosedXML/ClosedXML/ClosedXML_Examples/ClosedXML_Examples.csproj
index efddf26..e7e95d6 100644
--- a/ClosedXML/ClosedXML/ClosedXML_Examples/ClosedXML_Examples.csproj
+++ b/ClosedXML/ClosedXML/ClosedXML_Examples/ClosedXML_Examples.csproj
@@ -90,6 +90,7 @@
+
diff --git a/ClosedXML/ClosedXML/ClosedXML_Examples/Creating/CreateFiles.cs b/ClosedXML/ClosedXML/ClosedXML_Examples/Creating/CreateFiles.cs
index 3065bf7..5c703dc 100644
--- a/ClosedXML/ClosedXML/ClosedXML_Examples/Creating/CreateFiles.cs
+++ b/ClosedXML/ClosedXML/ClosedXML_Examples/Creating/CreateFiles.cs
@@ -72,6 +72,7 @@
new DataValidation().Create(@"C:\Excel Files\Created\DataValidation.xlsx");
new HideSheets().Create(@"C:\Excel Files\Created\HideSheets.xlsx");
new SheetProtection().Create(@"C:\Excel Files\Created\SheetProtection.xlsx");
+ new AutoFilter().Create(@"C:\Excel Files\Created\AutoFilter.xlsx");
}
}
}
diff --git a/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/AutoFilter.cs b/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/AutoFilter.cs
new file mode 100644
index 0000000..4532b08
--- /dev/null
+++ b/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/AutoFilter.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ClosedXML.Excel;
+
+using System.Drawing;
+
+namespace ClosedXML_Examples.Misc
+{
+ public class AutoFilter
+ {
+ #region Variables
+
+ // Public
+
+ // Private
+
+
+ #endregion
+
+ #region Properties
+
+ // Public
+
+ // Private
+
+ // Override
+
+
+ #endregion
+
+ #region Events
+
+ // Public
+
+ // Private
+
+ // Override
+
+
+ #endregion
+
+ #region Methods
+
+ // Public
+ public void Create(String filePath)
+ {
+ var wb = new XLWorkbook();
+ var ws = wb.Worksheets.Add("AutoFilter");
+ ws.Cell("A1").Value = "Names";
+ ws.Cell("A2").Value = "John";
+ ws.Cell("A3").Value = "Hank";
+ ws.Cell("A4").Value = "Dagny";
+
+ ws.RangeUsed().SetAutoFilter();
+
+ // Your can turn off the autofilter in three ways:
+ // 1) worksheet.AutoFilterRange.SetAutoFilter(false)
+ // 2) worksheet.AutoFilterRange = null
+ // 3) Pick any range in the worksheet and call range.SetAutoFilter(false);
+
+ wb.SaveAs(filePath);
+ }
+
+ // Private
+
+ // Override
+
+
+ #endregion
+ }
+}
diff --git a/ClosedXML/ClosedXML/ClosedXML_Sandbox/Program.cs b/ClosedXML/ClosedXML/ClosedXML_Sandbox/Program.cs
index 32e70df..bceb144 100644
--- a/ClosedXML/ClosedXML/ClosedXML_Sandbox/Program.cs
+++ b/ClosedXML/ClosedXML/ClosedXML_Sandbox/Program.cs
@@ -14,14 +14,40 @@
{
static void Main(string[] args)
{
- //var fileName = "DifferentKinds";
+ //var fileName = "BasicTable";
//var fileName = "Sandbox";
- var fileName = "Issue_6375";
- var wb = new XLWorkbook(String.Format(@"c:\Excel Files\ForTesting\{0}.xlsx", fileName));
+ var fileName = "Issue_6429";
+ var sourceFile = new XLWorkbook(String.Format(@"c:\Excel Files\ForTesting\{0}.xlsm", fileName));
//var wb = new XLWorkbook();
- //wbSource.Worksheet(1).CopyTo(wb, "Sheet1");
- //String source = @"c:\Excel Files\Created\{0}.xlsx";
+
+ using (var tempStream = new FileStream(String.Format(@"c:\Excel Files\ForTesting\{0}_Saved.xlsm", fileName), FileMode.Create))
+ {
+ sourceFile.SaveAs(tempStream);
+ }
+ sourceFile.SaveAs(@"c:\Excel Files\ForTesting\Issue_6429_FileToFile.xlsm");
+ using (var stream = new FileStream(@"c:\Excel Files\ForTesting\Issue_6429_FileToStream.xlsm", FileMode.Create))
+ {
+ sourceFile.SaveAs(stream);
+ }
+
+ using (var stream = new FileStream(
+ String.Format(@"c:\Excel Files\ForTesting\{0}.xlsm", fileName), FileMode.Open))
+ {
+ var sourceStream = new XLWorkbook(stream);
+ sourceStream.SaveAs(@"c:\Excel Files\ForTesting\Issue_6429_StreamToFile.xlsm");
+
+ using (var stream2 = new FileStream(@"c:\Excel Files\ForTesting\Issue_6429_StreamToStream.xlsm", FileMode.Create))
+ {
+ sourceStream.SaveAs(stream2);
+ }
+ }
+
+ //var ws = wb.Worksheet(1);
+ //var table = ws.RangeUsed();
+ //var newColumn = table.Column(1).InsertColumnsAfter(1).Single();
+ //table.Column(1).CopyTo(newColumn);
+ //newColumn.SetAutoFilter();
//CopyWorksheets(String.Format(source, "UsingTables"), wb);
//CopyWorksheets(String.Format(source, "NamedRanges"), wb);
@@ -35,7 +61,7 @@
//CopyWorksheets(String.Format(source, "DataValidation"), wb);
//CopyWorksheets(String.Format(source, "Hyperlinks"), wb);
- wb.SaveAs(String.Format(@"c:\Excel Files\ForTesting\{0}_Saved.xlsx", fileName));
+ //wb.SaveAs(String.Format(@"c:\Excel Files\ForTesting\{0}_Saved.xlsm", fileName));
}
static void CopyWorksheets(String source, XLWorkbook target)