Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/articles/breakingchanges.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,9 @@ Renaming worksheet's will now change the formula correctly to include single quo
`ExcelColor.Tint` from `decimal` to `double`.

### 8.0.2
* Removed base class from ExcelVmlDrawingPosition and with that the Load, UpdateXml methods and the RowOff and ColOff properties as they were duplicates.
* Removed base class from ExcelVmlDrawingPosition and with that the Load, UpdateXml methods and the RowOff and ColOff properties as they were duplicates.

### 8.5.5
* `ws.Cells["A1"].RichText` no longer sets cells with `null` to `string.empty`
* .RichText no longer sets the cell or contents to be RichText automatically.
This is instead done when properties such as; `.Text`, `.Add` or `.Insert` are set on the .RichText property.
7 changes: 7 additions & 0 deletions docs/articles/fixedissues.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Features / Fixed issues - EPPlus 8

## Version 8.5.5
### Minor Features
* Ranges can now convert their values to richText via ´ConvertToRichText()´ e.g. ´ws.Cells["A1"].ConvertToRichText()´
### Fixed issues
* Several issues related to RichText in ranges. Simply looking at the .RichText attribute no longer changes the cell value. Setting a propert e.g. ´range.RichText.Text = "Hi"´ or using ConvertToRichText() actually changes the value.

## Version 8.5.4
### Minor Features
* Added ´IncludeInHtmlOnly´ option to the ´ePictureInclude´ enum. This allows the HTML Exporter to include pictures directly in the HTML output rather than in the CSS.
Expand Down
46 changes: 28 additions & 18 deletions src/EPPlus/ExcelRangeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,27 @@ Date Author Change
*************************************************************************************************
01/27/2020 EPPlus Software AB Initial release EPPlus 5
*************************************************************************************************/
using System;
using System.Collections.Generic;
using OfficeOpenXml.FormulaParsing;
using OfficeOpenXml.Style;
using System.Globalization;
using System.Collections;
using OfficeOpenXml.Table;
using OfficeOpenXml.DataValidation;
using OfficeOpenXml.CellPictures;
using OfficeOpenXml.ConditionalFormatting;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using OfficeOpenXml.Core;
using OfficeOpenXml.Core.CellStore;
using OfficeOpenXml.Core.Worksheet;
using OfficeOpenXml.ThreadedComments;
using OfficeOpenXml.CellPictures;
using OfficeOpenXml.Sorting;
using OfficeOpenXml.DataValidation;
using OfficeOpenXml.Export.HtmlExport.Interfaces;
using OfficeOpenXml.FormulaParsing;
using OfficeOpenXml.FormulaParsing.Excel.Functions;
using OfficeOpenXml.Utils.TypeConversion;
using OfficeOpenXml.Utils.String;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using OfficeOpenXml.Sorting;
using OfficeOpenXml.Style;
using OfficeOpenXml.Table;
using OfficeOpenXml.ThreadedComments;
using OfficeOpenXml.Utils.Cell;
using static OfficeOpenXml.ExcelWorksheet;
using System.Linq;
using OfficeOpenXml.Utils.String;
using OfficeOpenXml.Utils.TypeConversion;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;

namespace OfficeOpenXml
{
Expand Down Expand Up @@ -1330,8 +1328,10 @@ public bool IsRichText
var isRt = _worksheet._flags.GetFlagValue(_fromRow, _fromCol, CellFlags.RichText);
if (isRt)
{
_rtc = _worksheet.GetRichText(_fromRow, _fromCol, this);
return _rtc.Count > 0;
//Do not update _rtc. This is a boolean getter.
//It should not set any values even if they diff.
var couldBeEmptyRT = _worksheet.GetRichText(_fromRow, _fromCol, this);
return couldBeEmptyRT.Count > 0;
}
return isRt;
}
Expand Down Expand Up @@ -1457,6 +1457,16 @@ public ExcelRichTextCollection RichText
}
}

/// <summary>
/// Convert the contents of the top left cell of this range to a richtext string
/// And set the cell value as .RichText
/// </summary>
public ExcelRichTextCollection ConvertToRichText()
{
_rtc = _worksheet.ConvertCellValueToRichText(_fromRow, _fromCol, this);
return _rtc;
}

/// <summary>
/// Returns the comment object of the first cell in the range
/// </summary>
Expand Down
47 changes: 36 additions & 11 deletions src/EPPlus/ExcelWorksheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1515,30 +1515,55 @@ private void LoadHyperLinks(XmlReader xr)
delRelIds.ToList().ForEach(x => Part.DeleteRelationship(x));
}

internal ExcelRichTextCollection GetRichText(int row, int col, ExcelRangeBase r = null)
internal ExcelRichTextCollection ConvertCellValueToRichText(int row, int col, ExcelRangeBase r = null)
{
var v = GetCoreValueInner(row, col);
var isRt = _flags.GetFlagValue(row, col, CellFlags.RichText);

//If it already is rt then no need to actually convert
if (isRt && v._value is ExcelRichTextCollection rtc)
{
if (rtc._cells == null) rtc._cells = r;
return rtc;
}
else
{
var text = ValueToTextHandler.GetFormattedText(v._value, Workbook, v._styleId, false);
if (string.IsNullOrEmpty(text))
object textValue = v._value;
if (textValue != null && typeof(ExcelRichTextCollection) == textValue.GetType())
{
var item = new ExcelRichTextCollection(Workbook, r);
SetValue(row, col, item);
return item;
textValue = ((ExcelRichTextCollection)textValue).Text;
}
else

var text = ValueToTextHandler.GetFormattedText(textValue, Workbook, v._styleId, false);
var item = new ExcelRichTextCollection(text, r);
SetValue(row, col, item);

return item;
}
}

internal ExcelRichTextCollection GetRichText(int row, int col, ExcelRangeBase r = null)
{
var v = GetCoreValueInner(row, col);
var isRt = _flags.GetFlagValue(row, col, CellFlags.RichText);
if (isRt && v._value is ExcelRichTextCollection rtc)
{
if (rtc._cells == null) rtc._cells = r;
return rtc;
}
else
{
object textValue = v._value;
if (textValue != null && typeof(ExcelRichTextCollection) == textValue.GetType())
{
var item = new ExcelRichTextCollection(text, r);
SetValue(row, col, item);
return item;
//This should only really happen if e.g. rich-text from a Note is Set to a cell value
textValue = ((ExcelRichTextCollection)textValue).Text;
var text = ValueToTextHandler.GetFormattedText(textValue, Workbook, v._styleId, false);
var itemRt = new ExcelRichTextCollection(text, r);
return itemRt;
}
var item = new ExcelRichTextCollection(Workbook, r);
return item;
}
}

Expand Down Expand Up @@ -2287,7 +2312,7 @@ public object GetValue(int Row, int Column)
var v = GetValueInner(Row, Column);
if (v != null)
{
if (_flags.GetFlagValue(Row, Column, CellFlags.RichText))
if (_flags.GetFlagValue(Row, Column, CellFlags.RichText) && Cells[Row, Column].IsRichText)
{
return (object)Cells[Row, Column].RichText.Text;
}
Expand Down
36 changes: 26 additions & 10 deletions src/EPPlus/Style/RichText/ExcelRichTextCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,14 @@ Date Author Change
*************************************************************************************************
01/27/2020 EPPlus Software AB Initial release EPPlus 5
*************************************************************************************************/
using OfficeOpenXml.Utils.TypeConversion;
using OfficeOpenXml.Utils.XML;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Drawing;
using System.Globalization;
using OfficeOpenXml.Drawing.Style.Coloring;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Statistical;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using OfficeOpenXml.Utils.XML;
using OfficeOpenXml.Utils.TypeConversion;
using System.Text;
using System.Xml;

namespace OfficeOpenXml.Style
{
Expand All @@ -40,7 +35,6 @@ internal ExcelRichTextCollection(ExcelWorkbook wb, ExcelRangeBase cells)
{
_wb = wb;
_cells = cells;
_cells._worksheet._flags.SetFlagValue(_cells._fromRow, _cells._fromCol, true, CellFlags.RichText);
}

internal ExcelRichTextCollection(string s, ExcelRangeBase cells)
Expand Down Expand Up @@ -162,6 +156,15 @@ public ExcelRichText Insert(int index, string text)
{
CheckDeleted();
if (text == null) throw new ArgumentException("Text can't be null", "text");

//If just a note we can't clear formulas on the cell itself.
if (_isComment == false)
{
//We MUST clear formulas before setting richtext
//To ensure calculate does not create missmatch between formula and richtext.
_cells.ClearFormulas();
}

var rt = new ExcelRichText(text, this);
rt.PreserveSpace = true;
int prevIndex = 0;
Expand Down Expand Up @@ -204,8 +207,19 @@ public ExcelRichText Insert(int index, string text)
{
rt.Color = Color.FromArgb(hex);
}

//If just a note we cannot set rich text flag on the cell itself.
if (_isComment == false)
{
//If the range value is not richtext it is now.
//Must set value first in order to not overwrite flags after.
if (_cells.Value != this)
{
//var flags = _cells._worksheet._flags;
_cells._worksheet._flags.GetFlagValue(_cells._fromRow, _cells._fromCol, CellFlags.RichText);
_cells.Value = this;
}
//If not a note then we are a cell and can set the flag.
_cells._worksheet._flags.SetFlagValue(_cells._fromRow, _cells._fromCol, true, CellFlags.RichText);
}
}
Expand All @@ -220,6 +234,8 @@ public void Clear()
{
CheckDeleted();
_list.Clear();
_cells._worksheet._flags.SetFlagValue(_cells._fromRow, _cells._fromCol, false, CellFlags.RichText);
_cells.Value = string.Empty;
}
/// <summary>
/// Removes an item at the specific index
Expand Down
2 changes: 1 addition & 1 deletion src/EPPlusTest/Core/Range/RangeRichTextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public void VerifyRichTextIsBlankIfAccess()
var ws = p.Workbook.Worksheets.Add("Sheet1");
var t = ws.Cells["A1"].RichText.Text;

Assert.AreEqual(string.Empty, ws.Cells["A1"].Value);
Assert.AreEqual(null, ws.Cells["A1"].Value);
}
}
[TestMethod]
Expand Down
2 changes: 0 additions & 2 deletions src/EPPlusTest/Issues/ChartIssues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,6 @@ public void s1038()
var firstDrawing = drawingsWithinGroupShape[0];

firstDrawing.SetPosition(500, 500);
//drawingsWithinGroupShape[0].Position.Y = 2000;


SaveAndCleanup(package);
}
Expand Down
39 changes: 35 additions & 4 deletions src/EPPlusTest/Issues/RichDataIssues.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OfficeOpenXml;

namespace EPPlusTest.Issues
Expand Down Expand Up @@ -85,5 +81,40 @@ public void VerifyCalcError()
SaveAndCleanup(p);
}
}

[TestMethod]
public void AddingRichTextToFormulasShouldOverwrite()
{
using (var pck = OpenPackage("dirtyRT.xlsx", true))
{
var ws = pck.Workbook.Worksheets.Add("richText");

ws.Cells["A1"].Value = 1001.1d;
ws.Cells["C1"].Formula = "ROUND(A1, 1)";
ws.Cells["B1"].Formula = "\"My favorite number is: \"&TEXT(ROUND(A1,1),\"#,##0.00;(#,##0.00)\")";

ws.Cells["B1"].RichText.Add("My favorite number is: 1001.1");

var myFormula = ws.Cells["B1"].Formula;

Assert.IsTrue(string.IsNullOrEmpty(myFormula));
}
}

[TestMethod]
public void RtComment()
{
using(var p = OpenTemplatePackage("RtWithOldComment.xlsx"))
{
var ws = p.Workbook.Worksheets[0];

var isRichtext = ws.Cells["B3"];
var text = ws.Cells["B3"].RichText;
var rtComment = ws.Cells["B3"].Comment;
var rtFromComment = rtComment.RichText;

Assert.AreNotEqual(text.Text, rtFromComment.Text);
}
}
}
}
3 changes: 2 additions & 1 deletion src/EPPlusTest/Issues/StylingIssues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,8 @@ public void s1005()
Assert.IsTrue(origText.Contains("69928453.64000"));

ws1.Cells["D8"].Calculate();
var cellRich = ws1.Cells["D8"].RichText.Text;

var cellRich = ws1.Cells["D8"].ConvertToRichText().Text;

//Verify formatting has changed appropriately for calculated string
Assert.IsTrue(cellRich.Contains("0,80"));
Expand Down
41 changes: 41 additions & 0 deletions src/EPPlusTest/Style/RichTextTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -370,5 +370,46 @@ public void CheckRichTextProperties()
Assert.AreEqual("Arial", C4.RichText[1].FontName);

}

[TestMethod]
public void issue2214()
{
var p = new ExcelPackage();

//Ensure that 'getting' any properties does not change type
var ws = p.Workbook.Worksheets.Add("Sheet1");
ws.Cells["A1"].Value = 1D;

Assert.IsInstanceOfType(ws.Cells["A1"].Value, typeof(double));
var r = ws.Cells["A1"].RichText;
Assert.IsInstanceOfType(ws.Cells["A1"].Value, typeof(double));

var test = r.Text;
Assert.IsInstanceOfType(ws.Cells["A1"].Value, typeof(double));
Assert.IsFalse(ws.Cells["A1"].IsRichText);

//Assert that Setting the property does.
string text = "Hello";
r.Text = text;

Assert.IsTrue(ws.Cells["A1"].IsRichText);
Assert.IsInstanceOfType(ws.Cells["A1"].Value, typeof(string));
Assert.AreEqual(text, (string)ws.Cells["A1"].Value);
}

[TestMethod]
public void ConvertCellToRichText()
{
var p = new ExcelPackage();
var ws = p.Workbook.Worksheets.Add("Sheet1");
ws.Cells["A1"].Value = 1D;

ws.Cells["A1"].ConvertToRichText();

Assert.IsTrue(ws.Cells["A1"].IsRichText);
Assert.IsInstanceOfType(ws.Cells["A1"].Value, typeof(string));
Assert.AreEqual("1", (string)ws.Cells["A1"].Value);
Assert.AreEqual("1", ws.Cells["A1"].RichText.Text);
}
}
}
Loading