diff --git a/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML.csproj
index eb62794..c7da769 100644
--- a/ClosedXML/ClosedXML.csproj
+++ b/ClosedXML/ClosedXML.csproj
@@ -22,7 +22,7 @@
false
bin\Debug\
DEBUG;TRACE
- NET4
+ NET4;TRACE;DEBUG
prompt
4
1591
@@ -32,7 +32,7 @@
true
bin\Release\
TRACE
- NET4
+ NET4;TRACE
prompt
4
bin\Release\ClosedXML.xml
diff --git a/ClosedXML/Excel/XLWorkbook.cs b/ClosedXML/Excel/XLWorkbook.cs
index ac31b4e..3cfe9ef 100644
--- a/ClosedXML/Excel/XLWorkbook.cs
+++ b/ClosedXML/Excel/XLWorkbook.cs
@@ -175,7 +175,7 @@
private readonly Dictionary _stylesByStyle = new Dictionary();
public XLEventTracking EventTracking { get; set; }
-
+
internal Int32 GetStyleId(IXLStyle style)
{
Int32 cached;
@@ -411,16 +411,28 @@
///
public void Save()
{
+#if DEBUG
+ Save(true);
+#else
+ Save(false);
+#endif
+ }
+
+ ///
+ /// Saves the current workbook and optionally performs validation
+ ///
+ public void Save(bool validate)
+ {
checkForWorksheetsPresent();
if (_loadSource == XLLoadSource.New)
throw new Exception("This is a new file, please use one of the SaveAs methods.");
if (_loadSource == XLLoadSource.Stream)
{
- CreatePackage(_originalStream, false, _spreadsheetDocumentType);
+ CreatePackage(_originalStream, false, _spreadsheetDocumentType, validate);
}
else
- CreatePackage(_originalFile, _spreadsheetDocumentType);
+ CreatePackage(_originalFile, _spreadsheetDocumentType, validate);
}
///
@@ -428,6 +440,18 @@
///
public void SaveAs(String file)
{
+#if DEBUG
+ SaveAs(file, true);
+#else
+ SaveAs(file, false);
+#endif
+ }
+
+ ///
+ /// Saves the current workbook to a file and optionally validates it.
+ ///
+ public void SaveAs(String file, Boolean validate)
+ {
checkForWorksheetsPresent();
PathHelper.CreateDirectory(Path.GetDirectoryName(file));
if (_loadSource == XLLoadSource.New)
@@ -435,14 +459,14 @@
if (File.Exists(file))
File.Delete(file);
- CreatePackage(file, GetSpreadsheetDocumentType(file));
+ CreatePackage(file, GetSpreadsheetDocumentType(file), validate);
}
else if (_loadSource == XLLoadSource.File)
{
if (String.Compare(_originalFile.Trim(), file.Trim(), true) != 0)
File.Copy(_originalFile, file, true);
- CreatePackage(file, GetSpreadsheetDocumentType(file));
+ CreatePackage(file, GetSpreadsheetDocumentType(file), validate);
}
else if (_loadSource == XLLoadSource.Stream)
{
@@ -452,7 +476,7 @@
{
CopyStream(_originalStream, fileStream);
//fileStream.Position = 0;
- CreatePackage(fileStream, false, _spreadsheetDocumentType);
+ CreatePackage(fileStream, false, _spreadsheetDocumentType, validate);
fileStream.Close();
}
}
@@ -481,6 +505,18 @@
///
public void SaveAs(Stream stream)
{
+#if DEBUG
+ SaveAs(stream, true);
+#else
+ SaveAs(stream, false);
+#endif
+ }
+
+ ///
+ /// Saves the current workbook to a stream and optionally validates it.
+ ///
+ public void SaveAs(Stream stream, Boolean validate)
+ {
checkForWorksheetsPresent();
if (_loadSource == XLLoadSource.New)
{
@@ -491,13 +527,13 @@
if (stream.CanRead && stream.CanSeek && stream.CanWrite)
{
// all is fine the package can be created in a direct way
- CreatePackage(stream, true, _spreadsheetDocumentType);
+ CreatePackage(stream, true, _spreadsheetDocumentType, validate);
}
else
{
// the harder way
MemoryStream ms = new MemoryStream();
- CreatePackage(ms, true, _spreadsheetDocumentType);
+ CreatePackage(ms, true, _spreadsheetDocumentType, validate);
// not really nessesary, because I changed CopyStream too.
// but for better understanding and if somebody in the future
// provide an changed version of CopyStream
@@ -512,7 +548,7 @@
CopyStream(fileStream, stream);
fileStream.Close();
}
- CreatePackage(stream, false, _spreadsheetDocumentType);
+ CreatePackage(stream, false, _spreadsheetDocumentType, validate);
}
else if (_loadSource == XLLoadSource.Stream)
{
@@ -520,7 +556,7 @@
if (_originalStream != stream)
CopyStream(_originalStream, stream);
- CreatePackage(stream, false, _spreadsheetDocumentType);
+ CreatePackage(stream, false, _spreadsheetDocumentType, validate);
}
}
@@ -589,24 +625,24 @@
return columns;
}
- #region Fields
+#region Fields
private readonly XLLoadSource _loadSource = XLLoadSource.New;
private readonly String _originalFile;
private readonly Stream _originalStream;
- #endregion
+#endregion
- #region Constructor
+#region Constructor
-
+
///
/// Creates a new Excel workbook.
///
public XLWorkbook()
:this(XLEventTracking.Enabled)
{
-
+
}
public XLWorkbook(XLEventTracking eventTracking)
@@ -665,7 +701,7 @@
/// The stream to open.
public XLWorkbook(Stream stream):this(stream, XLEventTracking.Enabled)
{
-
+
}
public XLWorkbook(Stream stream, XLEventTracking eventTracking)
@@ -676,9 +712,9 @@
Load(stream);
}
- #endregion
+#endregion
- #region Nested type: UnsupportedSheet
+#region Nested type: UnsupportedSheet
internal sealed class UnsupportedSheet
{
@@ -687,7 +723,7 @@
public Int32 Position;
}
- #endregion
+#endregion
public IXLCell Cell(String namedCell)
{
@@ -814,4 +850,4 @@
LockWindows = LockWindows;
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML/Excel/XLWorkbook_Save.cs b/ClosedXML/Excel/XLWorkbook_Save.cs
index 19fdd69..9b5c432 100644
--- a/ClosedXML/Excel/XLWorkbook_Save.cs
+++ b/ClosedXML/Excel/XLWorkbook_Save.cs
@@ -10,6 +10,7 @@
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.VariantTypes;
+using DocumentFormat.OpenXml.Validation;
using DocumentFormat.OpenXml.Vml.Office;
using DocumentFormat.OpenXml.Vml.Spreadsheet;
using Vml = DocumentFormat.OpenXml.Vml;
@@ -43,7 +44,6 @@
using RunProperties = DocumentFormat.OpenXml.Spreadsheet.RunProperties;
using VerticalTextAlignment = DocumentFormat.OpenXml.Spreadsheet.VerticalTextAlignment;
-
namespace ClosedXML.Excel
{
public partial class XLWorkbook
@@ -80,7 +80,19 @@
}
}
- private void CreatePackage(String filePath, SpreadsheetDocumentType spreadsheetDocumentType)
+ private bool Validate(SpreadsheetDocument package)
+ {
+ var validator = new OpenXmlValidator();
+ var errors = validator.Validate(package);
+ if (errors.Any())
+ {
+ var message = string.Join("\r\n", errors.Select(e => string.Format("{0} in {1}", e.Description, e.Path.XPath)).ToArray());
+ throw new ApplicationException(message);
+ }
+ return true;
+ }
+
+ private void CreatePackage(String filePath, SpreadsheetDocumentType spreadsheetDocumentType, bool validate)
{
PathHelper.CreateDirectory(Path.GetDirectoryName(filePath));
var package = File.Exists(filePath)
@@ -90,11 +102,11 @@
using (package)
{
CreateParts(package);
- //package.Close();
+ if (validate) Validate(package);
}
}
- private void CreatePackage(Stream stream, bool newStream, SpreadsheetDocumentType spreadsheetDocumentType)
+ private void CreatePackage(Stream stream, bool newStream, SpreadsheetDocumentType spreadsheetDocumentType, bool validate)
{
var package = newStream
? SpreadsheetDocument.Create(stream, spreadsheetDocumentType)
@@ -103,7 +115,7 @@
using (package)
{
CreateParts(package);
- //package.Close();
+ if (validate) Validate(package);
}
}
diff --git a/ClosedXML_Tests/Excel/Columns/ColumnTests.cs b/ClosedXML_Tests/Excel/Columns/ColumnTests.cs
index 0a98c4f..aa28593 100644
--- a/ClosedXML_Tests/Excel/Columns/ColumnTests.cs
+++ b/ClosedXML_Tests/Excel/Columns/ColumnTests.cs
@@ -108,7 +108,7 @@
IXLColumn columnIns = ws.Column(2).InsertColumnsBefore(1).First();
string outputPath = Path.Combine(TestHelper.TestsOutputDirectory, @"ForTesting\Sandbox.xlsx");
- wb.SaveAs(outputPath);
+ wb.SaveAs(outputPath, true);
Assert.AreEqual(XLColor.Red, ws.Column(1).Cell(1).Style.Fill.BackgroundColor);
Assert.AreEqual(XLColor.Red, ws.Column(1).Cell(2).Style.Fill.BackgroundColor);
@@ -237,4 +237,4 @@
Assert.AreEqual(2, lastCoUsed);
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Excel/PageSetup/HeaderFooterTests.cs b/ClosedXML_Tests/Excel/PageSetup/HeaderFooterTests.cs
index d1748a9..18fe221 100644
--- a/ClosedXML_Tests/Excel/PageSetup/HeaderFooterTests.cs
+++ b/ClosedXML_Tests/Excel/PageSetup/HeaderFooterTests.cs
@@ -17,7 +17,7 @@
ws.PageSetup.Header.Center.AddText("Initial page header", XLHFOccurrence.EvenPages);
var ms = new MemoryStream();
- wb.SaveAs(ms);
+ wb.SaveAs(ms, true);
wb = new XLWorkbook(ms);
ws = wb.Worksheets.First();
@@ -25,7 +25,7 @@
ws.PageSetup.Header.Center.Clear();
ws.PageSetup.Header.Center.AddText("Changed header", XLHFOccurrence.EvenPages);
- wb.SaveAs(ms);
+ wb.SaveAs(ms, true);
wb = new XLWorkbook(ms);
ws = wb.Worksheets.First();
@@ -34,4 +34,4 @@
Assert.AreEqual("Changed header", newHeader);
}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs b/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
index c90f624..22bd7c6 100644
--- a/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
+++ b/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
@@ -178,7 +178,7 @@
// ws.NamedRanges.Add("TestRange", "\"Hello\"");
// using (MemoryStream memoryStream = new MemoryStream())
// {
- // wb.SaveAs(memoryStream);
+ // wb.SaveAs(memoryStream, true);
// var wb2 = new XLWorkbook(memoryStream);
// var text = wb2.Worksheet("Sheet1").NamedRanges.First()
// memoryStream.Close();
@@ -187,4 +187,4 @@
//}
}
-}
\ No newline at end of file
+}
diff --git a/ClosedXML_Tests/Excel/Tables/TablesTests.cs b/ClosedXML_Tests/Excel/Tables/TablesTests.cs
index d7a8bac..ea27d0d 100644
--- a/ClosedXML_Tests/Excel/Tables/TablesTests.cs
+++ b/ClosedXML_Tests/Excel/Tables/TablesTests.cs
@@ -40,14 +40,14 @@
public void CanSaveTableCreatedFromEmptyDataTable()
{
var dt = new DataTable("sheet1");
- dt.Columns.Add("col1", typeof(string));
- dt.Columns.Add("col2", typeof(double));
+ dt.Columns.Add("col1", typeof (string));
+ dt.Columns.Add("col2", typeof (double));
var wb = new XLWorkbook();
wb.AddWorksheet(dt);
using (var ms = new MemoryStream())
- wb.SaveAs(ms);
+ wb.SaveAs(ms, true);
}
[Test]
@@ -59,7 +59,7 @@
ws.Range("A1").CreateTable();
using (var ms = new MemoryStream())
- wb.SaveAs(ms);
+ wb.SaveAs(ms, true);
}
[Test]
@@ -101,7 +101,7 @@
ws.RangeUsed().CreateTable();
using (var ms = new MemoryStream())
{
- wb.SaveAs(ms);
+ wb.SaveAs(ms, true);
var wb2 = new XLWorkbook(ms);
IXLWorksheet ws2 = wb2.Worksheet(1);
IXLTable table2 = ws2.Table(0);
@@ -131,7 +131,7 @@
using (var ms = new MemoryStream())
{
- wb.SaveAs(ms);
+ wb.SaveAs(ms, true);
var wb2 = new XLWorkbook(ms);
IXLWorksheet ws2 = wb2.Worksheet(1);
IXLTable table2 = ws2.Table(0);
@@ -144,8 +144,8 @@
public void TableCreatedFromEmptyDataTable()
{
var dt = new DataTable("sheet1");
- dt.Columns.Add("col1", typeof(string));
- dt.Columns.Add("col2", typeof(double));
+ dt.Columns.Add("col1", typeof (string));
+ dt.Columns.Add("col2", typeof (double));
var wb = new XLWorkbook();
IXLWorksheet ws = wb.AddWorksheet("Sheet1");
diff --git a/ClosedXML_Tests/TestHelper.cs b/ClosedXML_Tests/TestHelper.cs
index be509a2..07576df 100644
--- a/ClosedXML_Tests/TestHelper.cs
+++ b/ClosedXML_Tests/TestHelper.cs
@@ -19,22 +19,22 @@
//Note: Run example tests parameters
public static string TestsOutputDirectory
{
- get {
- return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
+ get {
+ return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
}
}
public const string ActualTestResultPostFix = "";
public static readonly string TestsExampleOutputDirectory = Path.Combine(TestsOutputDirectory, "Examples");
-
+
private const bool CompareWithResources = true;
private static readonly ResourceFileExtractor _extractor = new ResourceFileExtractor(null, ".Resource.Examples.");
public static void SaveWorkbook(XLWorkbook workbook, string fileName)
{
- workbook.SaveAs(Path.Combine(TestsOutputDirectory, fileName));
+ workbook.SaveAs(Path.Combine(TestsOutputDirectory, fileName), true);
}
public static void RunTestExample(string filePartName)
@@ -57,7 +57,7 @@
var filePath2 = Path.Combine(directory, fileName);
//Run test
example.Create(filePath1);
- new XLWorkbook(filePath1).SaveAs(filePath2);
+ new XLWorkbook(filePath1).SaveAs(filePath2, true);
bool success = true;
#pragma warning disable 162
try
@@ -102,4 +102,4 @@
}
}
}
-}
\ No newline at end of file
+}