diff --git a/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML.csproj
index 12bf76a..fc22ffe 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 c6084d6..2e69e73 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;
@@ -42,7 +43,6 @@
using RunProperties = DocumentFormat.OpenXml.Spreadsheet.RunProperties;
using VerticalTextAlignment = DocumentFormat.OpenXml.Spreadsheet.VerticalTextAlignment;
-
namespace ClosedXML.Excel
{
public partial class XLWorkbook
@@ -79,7 +79,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)
@@ -89,11 +101,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)
@@ -102,7 +114,7 @@
using (package)
{
CreateParts(package);
- //package.Close();
+ if (validate) Validate(package);
}
}
@@ -159,8 +171,8 @@
}
}
- // Get the CalculationChainPart
- //Note: An instance of this part type contains an ordered set of references to all cells in all worksheets in the
+ // Get the CalculationChainPart
+ //Note: An instance of this part type contains an ordered set of references to all cells in all worksheets in the
//workbook whose value is calculated from any formula
CalculationChainPart calChainPart;
@@ -194,7 +206,7 @@
var workbookPart = document.WorkbookPart ?? document.AddWorkbookPart();
var worksheets = WorksheetsInternal;
-
+
var partsToRemove = workbookPart.Parts.Where(s => worksheets.Deleted.Contains(s.RelationshipId)).ToList();
@@ -538,7 +550,7 @@
{
workbook.WorkbookProtection = null;
}
-
+
if (workbook.BookViews == null)
workbook.BookViews = new BookViews();
@@ -4064,7 +4076,7 @@
}
worksheetPart.Worksheet.InsertAfter(conditionalFormatting, previousElement);
previousElement = conditionalFormatting;
- cm.SetElement(XLWSContentManager.XLWSContents.ConditionalFormatting, conditionalFormatting);
+ cm.SetElement(XLWSContentManager.XLWSContents.ConditionalFormatting, conditionalFormatting);
}
}
@@ -4636,4 +4648,4 @@
#endregion
}
-}
\ No newline at end of file
+}