diff --git a/ClosedXML/Excel/XLWorkbook.cs b/ClosedXML/Excel/XLWorkbook.cs
index 645d536..e82a5a0 100644
--- a/ClosedXML/Excel/XLWorkbook.cs
+++ b/ClosedXML/Excel/XLWorkbook.cs
@@ -429,16 +429,16 @@
public void Save()
{
#if DEBUG
- Save(true);
+ Save(true, false);
#else
- Save(false);
+ Save(false, false);
#endif
}
///
/// Saves the current workbook and optionally performs validation
///
- public void Save(bool validate)
+ public void Save(Boolean validate, Boolean evaluateFormulae = false)
{
checkForWorksheetsPresent();
if (_loadSource == XLLoadSource.New)
@@ -446,10 +446,10 @@
if (_loadSource == XLLoadSource.Stream)
{
- CreatePackage(_originalStream, false, _spreadsheetDocumentType, validate);
+ CreatePackage(_originalStream, false, _spreadsheetDocumentType, validate, evaluateFormulae);
}
else
- CreatePackage(_originalFile, _spreadsheetDocumentType, validate);
+ CreatePackage(_originalFile, _spreadsheetDocumentType, validate, evaluateFormulae);
}
///
@@ -458,16 +458,16 @@
public void SaveAs(String file)
{
#if DEBUG
- SaveAs(file, true);
+ SaveAs(file, true, false);
#else
- SaveAs(file, false);
+ SaveAs(file, false, false);
#endif
}
///
/// Saves the current workbook to a file and optionally validates it.
///
- public void SaveAs(String file, Boolean validate)
+ public void SaveAs(String file, Boolean validate, Boolean evaluateFormulae = false)
{
checkForWorksheetsPresent();
PathHelper.CreateDirectory(Path.GetDirectoryName(file));
@@ -476,14 +476,14 @@
if (File.Exists(file))
File.Delete(file);
- CreatePackage(file, GetSpreadsheetDocumentType(file), validate);
+ CreatePackage(file, GetSpreadsheetDocumentType(file), validate, evaluateFormulae);
}
else if (_loadSource == XLLoadSource.File)
{
if (String.Compare(_originalFile.Trim(), file.Trim(), true) != 0)
File.Copy(_originalFile, file, true);
- CreatePackage(file, GetSpreadsheetDocumentType(file), validate);
+ CreatePackage(file, GetSpreadsheetDocumentType(file), validate, evaluateFormulae);
}
else if (_loadSource == XLLoadSource.Stream)
{
@@ -493,7 +493,7 @@
{
CopyStream(_originalStream, fileStream);
//fileStream.Position = 0;
- CreatePackage(fileStream, false, _spreadsheetDocumentType, validate);
+ CreatePackage(fileStream, false, _spreadsheetDocumentType, validate, evaluateFormulae);
fileStream.Close();
}
}
@@ -531,16 +531,16 @@
public void SaveAs(Stream stream)
{
#if DEBUG
- SaveAs(stream, true);
+ SaveAs(stream, true, false);
#else
- SaveAs(stream, false);
+ SaveAs(stream, false, false);
#endif
}
///
/// Saves the current workbook to a stream and optionally validates it.
///
- public void SaveAs(Stream stream, Boolean validate)
+ public void SaveAs(Stream stream, Boolean validate, Boolean evaluateFormulae = false)
{
checkForWorksheetsPresent();
if (_loadSource == XLLoadSource.New)
@@ -552,13 +552,13 @@
if (stream.CanRead && stream.CanSeek && stream.CanWrite)
{
// all is fine the package can be created in a direct way
- CreatePackage(stream, true, _spreadsheetDocumentType, validate);
+ CreatePackage(stream, true, _spreadsheetDocumentType, validate, evaluateFormulae);
}
else
{
// the harder way
MemoryStream ms = new MemoryStream();
- CreatePackage(ms, true, _spreadsheetDocumentType, validate);
+ CreatePackage(ms, true, _spreadsheetDocumentType, validate, evaluateFormulae);
// not really nessesary, because I changed CopyStream too.
// but for better understanding and if somebody in the future
// provide an changed version of CopyStream
@@ -573,7 +573,7 @@
CopyStream(fileStream, stream);
fileStream.Close();
}
- CreatePackage(stream, false, _spreadsheetDocumentType, validate);
+ CreatePackage(stream, false, _spreadsheetDocumentType, validate, evaluateFormulae);
}
else if (_loadSource == XLLoadSource.Stream)
{
@@ -581,7 +581,7 @@
if (_originalStream != stream)
CopyStream(_originalStream, stream);
- CreatePackage(stream, false, _spreadsheetDocumentType, validate);
+ CreatePackage(stream, false, _spreadsheetDocumentType, validate, evaluateFormulae);
}
}
diff --git a/ClosedXML/Excel/XLWorkbook_Save.cs b/ClosedXML/Excel/XLWorkbook_Save.cs
index 08994f1..9d68063 100644
--- a/ClosedXML/Excel/XLWorkbook_Save.cs
+++ b/ClosedXML/Excel/XLWorkbook_Save.cs
@@ -60,7 +60,7 @@
private static readonly EnumValue CvDate = new EnumValue(CellValues.Date);
private static readonly EnumValue CvBoolean = new EnumValue(CellValues.Boolean);
- private static EnumValue GetCellValue(XLCell xlCell)
+ private static EnumValue GetCellValueType(XLCell xlCell)
{
switch (xlCell.DataType)
{
@@ -105,7 +105,7 @@
return true;
}
- private void CreatePackage(String filePath, SpreadsheetDocumentType spreadsheetDocumentType, bool validate)
+ private void CreatePackage(String filePath, SpreadsheetDocumentType spreadsheetDocumentType, bool validate, bool evaluateFormulae)
{
PathHelper.CreateDirectory(Path.GetDirectoryName(filePath));
var package = File.Exists(filePath)
@@ -114,12 +114,12 @@
using (package)
{
- CreateParts(package);
+ CreateParts(package, evaluateFormulae);
if (validate) Validate(package);
}
}
- private void CreatePackage(Stream stream, bool newStream, SpreadsheetDocumentType spreadsheetDocumentType, bool validate)
+ private void CreatePackage(Stream stream, bool newStream, SpreadsheetDocumentType spreadsheetDocumentType, bool validate, bool evaluateFormulae)
{
var package = newStream
? SpreadsheetDocument.Create(stream, spreadsheetDocumentType)
@@ -127,7 +127,7 @@
using (package)
{
- CreateParts(package);
+ CreateParts(package, evaluateFormulae);
if (validate) Validate(package);
}
}
@@ -213,7 +213,7 @@
}
// Adds child parts and generates content of the specified part.
- private void CreateParts(SpreadsheetDocument document)
+ private void CreateParts(SpreadsheetDocument document, bool evaluateFormulae)
{
var context = new SaveContext();
@@ -311,7 +311,7 @@
GenerateVmlDrawingPartContent(vmlDrawingPart, worksheet, context);
}
- GenerateWorksheetPartContent(worksheetPart, worksheet, context);
+ GenerateWorksheetPartContent(worksheetPart, worksheet, evaluateFormulae, context);
if (worksheet.PivotTables.Any())
{
@@ -3497,8 +3497,8 @@
#region GenerateWorksheetPartContent
- private static void GenerateWorksheetPartContent(WorksheetPart worksheetPart, XLWorksheet xlWorksheet,
- SaveContext context)
+ private static void GenerateWorksheetPartContent(
+ WorksheetPart worksheetPart, XLWorksheet xlWorksheet, bool evaluateFormulae, SaveContext context)
{
#region Worksheet
@@ -4066,10 +4066,10 @@
else
{
cell.CellFormula = null;
- cell.DataType = xlCell.DataType == XLCellValues.DateTime ? null : GetCellValue(xlCell);
+ cell.DataType = xlCell.DataType == XLCellValues.DateTime ? null : GetCellValueType(xlCell);
}
- if (!xlCell.HasFormula)
+ if (!xlCell.HasFormula || evaluateFormulae)
SetCellValue(xlCell, cell);
}
@@ -4584,6 +4584,23 @@
private static void SetCellValue(XLCell xlCell, Cell openXmlCell)
{
+ if (xlCell.HasFormula)
+ {
+ var cellValue = new CellValue();
+ try
+ {
+ cellValue.Text = xlCell.Value.ToString();
+ openXmlCell.DataType = new EnumValue(CellValues.String);
+ }
+ catch
+ {
+ cellValue = null;
+ }
+
+ openXmlCell.CellValue = cellValue;
+ return;
+ }
+
var dataType = xlCell.DataType;
if (dataType == XLCellValues.Text)
{
diff --git a/ClosedXML_Examples/ClosedXML_Examples.csproj b/ClosedXML_Examples/ClosedXML_Examples.csproj
index 155d094..c1074f7 100644
--- a/ClosedXML_Examples/ClosedXML_Examples.csproj
+++ b/ClosedXML_Examples/ClosedXML_Examples.csproj
@@ -109,6 +109,7 @@
+
diff --git a/ClosedXML_Examples/Misc/FormulasWithEvaluation.cs b/ClosedXML_Examples/Misc/FormulasWithEvaluation.cs
new file mode 100644
index 0000000..dca890e
--- /dev/null
+++ b/ClosedXML_Examples/Misc/FormulasWithEvaluation.cs
@@ -0,0 +1,16 @@
+using ClosedXML.Excel;
+
+namespace ClosedXML_Examples.Misc
+{
+ public class FormulasWithEvaluation : Formulas
+ {
+ public override void Create(string filePath)
+ {
+ base.Create(filePath);
+ using (var wb = new XLWorkbook(filePath))
+ {
+ wb.Save(true, true);
+ }
+ }
+ }
+}
diff --git a/ClosedXML_Tests/ClosedXML_Tests.csproj b/ClosedXML_Tests/ClosedXML_Tests.csproj
index 9eac192..d4c8a9a 100644
--- a/ClosedXML_Tests/ClosedXML_Tests.csproj
+++ b/ClosedXML_Tests/ClosedXML_Tests.csproj
@@ -153,6 +153,7 @@
+
diff --git a/ClosedXML_Tests/Examples/MiscTests.cs b/ClosedXML_Tests/Examples/MiscTests.cs
index 47865bc..928e9ab 100644
--- a/ClosedXML_Tests/Examples/MiscTests.cs
+++ b/ClosedXML_Tests/Examples/MiscTests.cs
@@ -98,6 +98,12 @@
}
[Test]
+ public void FormulasWithEvaluation()
+ {
+ TestHelper.RunTestExample(@"Misc\FormulasWithEvaluation.xlsx", true);
+ }
+
+ [Test]
public void FreezePanes()
{
TestHelper.RunTestExample(@"Misc\FreezePanes.xlsx");
diff --git a/ClosedXML_Tests/Resource/Examples/Misc/FormulasWithEvaluation.xlsx b/ClosedXML_Tests/Resource/Examples/Misc/FormulasWithEvaluation.xlsx
new file mode 100644
index 0000000..c4a24f7
--- /dev/null
+++ b/ClosedXML_Tests/Resource/Examples/Misc/FormulasWithEvaluation.xlsx
Binary files differ
diff --git a/ClosedXML_Tests/TestHelper.cs b/ClosedXML_Tests/TestHelper.cs
index 477facf..98929bc 100644
--- a/ClosedXML_Tests/TestHelper.cs
+++ b/ClosedXML_Tests/TestHelper.cs
@@ -53,7 +53,7 @@
}
}
- public static void RunTestExample(string filePartName)
+ public static void RunTestExample(string filePartName, bool evaluateFormulae = false)
where T : IXLExample, new()
{
// Make sure tests run on a deterministic culture
@@ -74,7 +74,7 @@
var filePath2 = Path.Combine(directory, fileName);
//Run test
example.Create(filePath1);
- new XLWorkbook(filePath1).SaveAs(filePath2, true);
+ new XLWorkbook(filePath1).SaveAs(filePath2, true, evaluateFormulae);
bool success = true;
#pragma warning disable 162
try