Skip to content

Commit

Permalink
Feature/rich text (#1352)
Browse files Browse the repository at this point in the history
* Fixes issue #1292

* Bug/s608 first sheet deletion (#1294)

* Beggining of solution

* Simplified solution. Added tests and exception

* Cleanup

* Fixes issue #1298

* Added test

* Fixed test

* Fixes issue #1298 (#1299)

* Fixes issue #1298

* Added test

* Fixed test

* EPPlus version 7.0.9

* Fixes issue #1302

* Fixes issue 1304

* Fixes issue #1308

* Fixes #1313. Better handling of defined names and encode ExcelNamedRange.NameValue property on save

* Added new test class

* Bug/s615 data validation read (#1307)

* Added new test removed issue test

* Added readwrite to test for confirmation

* Added fixed issues

* Secured DataValidation reading. Fixed i1312

* Non-working strict solution

* Resolved dataValidation read issues. Added docs

* Cleanup and commenting

* Make test happy in production

---------

Co-authored-by: Jan Källman <[email protected]>

* Fixes issue #1320 (#1322)

* Bug/issue1321 (#1324)

* Fixes issue #1320

* Fixes issue #1321

* Added CellStore Test

* #1329 - adjusted ActiveTab when moving worksheets

* #1327 - EPPlus removed all styling when setting a Table's CalculatedFormula to an empty string

* Progress on RichText optmimzation.

* Added more tests

* Fixed color auto property not being read properly

* #1327 - fixed failing unit test, added ClearFormulas call

* Deleted old files and fixing tests.

* #1332 - Intersect operator was replaced with 'isc' when copying cells (#1333)

* #1332 - Intersect operator was replaced with 'isc' when copying cells

* #1332 - removed the added static DefaultPreserveWhiteSpace from SourceCodeTokenizer

* Fixed some more tests not passing.

* Updated a test.

* Fixes issue #1338

* Updated fixed issues

* Fixes issue #1341

* Bug/issue1338 (#1340)

* Fixes issue #1338

* Updated fixed issues

* EPPlus version 7.0.10

* Fixed rich text for more tests.

* Fixes issue #1335

* Fixes #1343. Writing and loading pivot table attribute on CFs (#1344)

* Fixes #1343. Writing and loading pivot table attribute on CFs

* Added docs

* Bug/s635 insert row (#1346)

* Fixes #1345 fixed read exception faulty while loop

* Added template-free test

* fixed LastToken and added docs

---------

Co-authored-by: Jan Källman <[email protected]>

* Fixed richtext issues.

* Fixed issue when having multiple spaces is a intersect operator and use keep whitespaces

* Fixed issue with rich text comments not being saved & rich text attrobutes not being copied.

* Cleaned up richtexttests

* Added copy worksheet test for richtext

* Removed RichTextAttributes and using properties again.

* Moved files and deleted new folder.

* Fixed GetIndexColor - as it has been moved to Styles

* Fixed some issues with failed tests

* Ensured mergedcells border can be null

* Fixed remove in ExcelParagraphCollection.

* Removed commented code.

---------

Co-authored-by: JanKallman <[email protected]>
Co-authored-by: OssianEPPlus <[email protected]>
Co-authored-by: swmal <[email protected]>
Co-authored-by: Ossian Edström <[email protected]>
  • Loading branch information
5 people committed Mar 18, 2024
1 parent f8e39b4 commit 952ded8
Show file tree
Hide file tree
Showing 29 changed files with 1,544 additions and 819 deletions.
1 change: 1 addition & 0 deletions docs/articles/fixedissues.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Special signs such as `'` when last in a formula would throw an exception in rare cases.
* Reading Conditional Formattings with property PivotTable = true failed to read in property.
* Tokenize an intersect operator with the _keepWhitespaces set, caused both a white-space token and a intesect operator to be added.
* The HTML exporter now exports all conditionalFormattings except Iconsets and Databars

## Version 7.0.10
### Fixed issues
Expand Down
8 changes: 7 additions & 1 deletion src/EPPlus/Core/RangeCopyHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using OfficeOpenXml.Drawing;
using OfficeOpenXml.Drawing.Interfaces;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
using OfficeOpenXml.Style;
using OfficeOpenXml.Style.Dxf;
using OfficeOpenXml.ThreadedComments;
using OfficeOpenXml.Utils;
Expand Down Expand Up @@ -385,6 +386,11 @@ private void CopyValuesToDestination()
{
_destination._worksheet.SetValueStyleIdInner(cell.Row, cell.Column, cell.Value, cell.StyleID ?? 0);
}
if(cell.Value is ExcelRichTextCollection)
{
var t = new ExcelRichTextCollection((Style.ExcelRichTextCollection)cell.Value, _destination);
_destination._worksheet.SetValueInner(cell.Row, cell.Column,t);
}

if ((EnumUtil.HasNotFlag(_copyOptions, ExcelRangeCopyOptionFlags.ExcludeFormulas) && EnumUtil.HasNotFlag(_copyOptions, ExcelRangeCopyOptionFlags.ExcludeValues)) &&
cell.Formula != null)
Expand Down Expand Up @@ -453,7 +459,7 @@ private static void CopyComment(ExcelRangeBase destination, CopiedCell cell)
c.Column = cell.Column-1;

c._commentHelper.TopNode.InnerXml = cell.Comment._commentHelper.TopNode.InnerXml;
c.RichText = new Style.ExcelRichTextCollection(c._commentHelper.NameSpaceManager, c._commentHelper.GetNode("d:text"), destination._worksheet);
c.RichText = new Style.ExcelRichTextCollection(cell.Comment.RichText, destination);
//Add relation to image used for filling the comment
if(cell.Comment.Fill.Style == Drawing.Vml.eVmlFillType.Frame ||
cell.Comment.Fill.Style == Drawing.Vml.eVmlFillType.Tile ||
Expand Down
76 changes: 45 additions & 31 deletions src/EPPlus/Core/Worksheet/XmlWriter/WorksheetXmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
using System.Linq;
using System.Security;
using System.Text;
using static OfficeOpenXml.ExcelWorkbook;
using static OfficeOpenXml.ExcelWorksheet;

namespace OfficeOpenXml.Core.Worksheet.XmlWriter
Expand Down Expand Up @@ -372,7 +373,8 @@ private void UpdateRowCellData(StreamWriter sw, string prefix)
var vTag = prefix + "v";
var nsf = _package.Workbook.FormulaParser.ParsingContext.Configuration.FunctionRepository.NamespaceFunctions;
StringBuilder sbXml = new StringBuilder();
var ss = _package.Workbook._sharedStrings;
var ssLookup = _package.Workbook._sharedStringsLookup;
var ssList = _package.Workbook._sharedStringsListNew;
var cache = new StringBuilder();
cache.Append($"<{sheetDataTag}>");

Expand Down Expand Up @@ -518,47 +520,59 @@ private void UpdateRowCellData(StreamWriter sw, string prefix)
}
else if (v != null)
{
if (v is System.Collections.IEnumerable enumResult && !(v is string))
if (v is ExcelRichTextCollection rt)
{
var e = enumResult.GetEnumerator();
if (e.MoveNext() && e.Current != null)
v = e.Current;
else
v = string.Empty;
}
if ((TypeCompat.IsPrimitive(v) || v is double || v is decimal || v is DateTime || v is TimeSpan) && !(v is char))
{
cache.Append($"<{cTag} r=\"{cse.CellAddress}\" s=\"{styleID}\"{ConvertUtil.GetCellType(v)}{mdAttr}>");
cache.Append($"{GetFormulaValue(v, prefix)}</{cTag}>");
}
else if(v is ExcelErrorValue e)
{
cache.Append($"<{cTag} r=\"{cse.CellAddress}\" s=\"{styleID}\"{ConvertUtil.GetCellType(v)}{mdAttr}>");
cache.Append($"{GetFormulaValue(v, prefix)}</{cTag}>");
var s = rt.GetXML();
if (!ssLookup.TryGetValue(s, out int ix))
{
ix = ssLookup.Count;
ssLookup.Add(s, ix);
ssList.Add(new SharedStringRichTextItem() { RichText = rt, Position = ix });
}
cache.Append($"<{cTag} r=\"{cse.CellAddress}\" s=\"{styleID}\" t=\"s\"{mdAttr}>");
cache.Append($"<{vTag}>{ix}</{vTag}></{cTag}>");
}
else
{
var s = Convert.ToString(v);
if (s == null) //If for example a struct
if (v is System.Collections.IEnumerable enumResult && !(v is string))
{
s = v.ToString();
if (s == null)
{
s = "";
}
var e = enumResult.GetEnumerator();
if (e.MoveNext() && e.Current != null)
v = e.Current;
else
v = string.Empty;
}
if ((TypeCompat.IsPrimitive(v) || v is double || v is decimal || v is DateTime || v is TimeSpan) && !(v is char))
{
cache.Append($"<{cTag} r=\"{cse.CellAddress}\" s=\"{styleID}\"{ConvertUtil.GetCellType(v)}{mdAttr}>");
cache.Append($"{GetFormulaValue(v, prefix)}</{cTag}>");
}
int ix;
if (!ss.ContainsKey(s))
else if (v is ExcelErrorValue e)
{
ix = ss.Count;
ss.Add(s, new ExcelWorkbook.SharedStringItem() { isRichText = _ws._flags.GetFlagValue(cse.Row, cse.Column, CellFlags.RichText), pos = ix });
cache.Append($"<{cTag} r=\"{cse.CellAddress}\" s=\"{styleID}\"{ConvertUtil.GetCellType(v)}{mdAttr}>");
cache.Append($"{GetFormulaValue(v, prefix)}</{cTag}>");
}
else
{
ix = ss[s].pos;
var s = Convert.ToString(v);
if (s == null) //If for example a struct
{
s = v.ToString();
if (s == null)
{
s = "";
}
}
int ix;
if (!ssLookup.TryGetValue(s, out ix))
{
ix = ssLookup.Count;
ssLookup.Add(s, ix);
ssList.Add(new SharedStringTextItem() { Text = s, Position = ix });
}
cache.Append($"<{cTag} r=\"{cse.CellAddress}\" s=\"{styleID}\" t=\"s\"{mdAttr}>");
cache.Append($"<{vTag}>{ix}</{vTag}></{cTag}>");
}
cache.Append($"<{cTag} r=\"{cse.CellAddress}\" s=\"{styleID}\" t=\"s\"{mdAttr}>");
cache.Append($"<{vTag}>{ix}</{vTag}></{cTag}>");
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/EPPlus/ExcelComment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal ExcelComment(XmlNamespaceManager ns, XmlNode commentTopNode, ExcelRange
}

TopNode = cell.Worksheet.VmlDrawings[cell.Start.Row, cell.Start.Column].TopNode;
RichText = new ExcelRichTextCollection(ns,textElem, cell.Worksheet);
RichText = new ExcelRichTextCollection(ns,textElem, cell);
var tNode = textElem.SelectSingleNode("d:t", ns);
if (tNode != null)
{
Expand Down
7 changes: 7 additions & 0 deletions src/EPPlus/ExcelRangeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,13 @@ public bool IsRichText
}
set
{
if(value == true &&( Value == null || Value.ToString() == string.Empty))
{
if (_rtc == null)
{
_rtc = _worksheet.GetRichText(_fromRow, _fromCol, this);
}
}
SetIsRichTextFlag(value);
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/EPPlus/ExcelRangeBase_Save.cs
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,7 @@ private Core.CellStore.ExcelValue GetCellStoreValue(int row, int col)
var v = _worksheet.GetCoreValueInner(row, col);
if (_worksheet._flags.GetFlagValue(row, col, CellFlags.RichText))
{
var xml = new XmlDocument();
XmlHelper.LoadXmlSafe(xml, "<d:si xmlns:d=\"http:https://schemas.openxmlformats.org/spreadsheetml/2006/main\" >" + v._value.ToString() + "</d:si>", Encoding.UTF8);
var rt = new ExcelRichTextCollection(_worksheet.NameSpaceManager, xml.SelectSingleNode("d:si", _worksheet.NameSpaceManager), this);
var rt = (ExcelRichTextCollection)v._value;
v._value = rt.Text;
}
return v;
Expand Down
Loading

0 comments on commit 952ded8

Please sign in to comment.