Skip to content

Commit 768d707

Browse files
authored
Merge pull request #1711 from antony-liu/poi/v4.0-patch7
Some patches from poi
2 parents 73f5243 + 0564672 commit 768d707

39 files changed

+872
-90
lines changed

main/HSSF/UserModel/OperationEvaluatorFactory.cs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,31 +82,44 @@ public static ValueEval evaluate(OperationPtg ptg, ValueEval[] args,
8282
}
8383
Function result = _instancesByPtgClass[ptg];
8484

85+
FreeRefFunction udfFunc = null;
86+
if(result == null)
87+
{
88+
if(ptg is AbstractFunctionPtg) {
89+
AbstractFunctionPtg fptg = (AbstractFunctionPtg)ptg;
90+
int functionIndex = fptg.FunctionIndex;
91+
switch(functionIndex)
92+
{
93+
case FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT:
94+
udfFunc = Indirect.instance;
95+
break;
96+
case FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL:
97+
udfFunc = UserDefinedFunction.instance;
98+
break;
99+
default:
100+
result = FunctionEval.GetBasicFunction(functionIndex);
101+
break;
102+
}
103+
}
104+
}
105+
85106
if(result != null)
86107
{
87108
IEvaluationSheet evalSheet = ec.GetWorkbook().GetSheet(ec.SheetIndex);
88109
IEvaluationCell evalCell = evalSheet.GetCell(ec.RowIndex, ec.ColumnIndex);
89110

90-
if(evalCell.IsPartOfArrayFormulaGroup && result is IArrayFunction)
91-
return ((IArrayFunction) result).EvaluateArray(args, ec.RowIndex, ec.ColumnIndex);
111+
if(evalCell != null && (evalCell.IsPartOfArrayFormulaGroup || ec.IsArraymode)
112+
&& result is ArrayFunction)
92113

93-
return result.Evaluate(args, ec.RowIndex, (short) ec.ColumnIndex);
94-
}
114+
return ((IArrayFunction) result).EvaluateArray(args, ec.RowIndex, ec.ColumnIndex);
95115

96-
if(ptg is AbstractFunctionPtg)
116+
return result.Evaluate(args, ec.RowIndex, ec.ColumnIndex);
117+
}
118+
else if(udfFunc != null)
97119
{
98-
AbstractFunctionPtg fptg = (AbstractFunctionPtg)ptg;
99-
int functionIndex = fptg.FunctionIndex;
100-
switch(functionIndex)
101-
{
102-
case FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT:
103-
return Indirect.instance.Evaluate(args, ec);
104-
case FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL:
105-
return UserDefinedFunction.instance.Evaluate(args, ec);
106-
}
107-
108-
return FunctionEval.GetBasicFunction(functionIndex).Evaluate(args, ec.RowIndex, (short) ec.ColumnIndex);
120+
return udfFunc.Evaluate(args, ec);
109121
}
122+
110123
throw new RuntimeException("Unexpected operation ptg class (" + ptg.GetType().Name + ")");
111124
}
112125
}

main/SS/Formula/Eval/OperandResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ private static ValueEval ChooseSingleElementFromAreaInternal(AreaEval ae,
183183
// multi-column, multi-row area
184184
if (ae.ContainsRow(srcCellRow) && ae.ContainsColumn(srcCellCol))
185185
{
186-
return ae.GetAbsoluteValue(ae.FirstRow, ae.FirstColumn);
186+
return ae.GetAbsoluteValue(srcCellRow, srcCellCol);
187187
}
188188
throw EvaluationException.InvalidValue();
189189
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* ====================================================================
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
==================================================================== */
17+
18+
using System;
19+
using System.Collections;
20+
using System.Collections.Generic;
21+
using System.IO;
22+
using System.Text;
23+
24+
namespace NPOI.SS.Formula.Functions
25+
{
26+
/// <summary>
27+
/// Interface for those functions that evaluate arguments in array mode depending on context.
28+
/// </summary>
29+
public interface IArrayMode
30+
{
31+
32+
}
33+
}

main/SS/Formula/Functions/Index.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace NPOI.SS.Formula.Functions
3737
*
3838
* @author Josh Micich
3939
*/
40-
public class Index : Function2Arg, Function3Arg, Function4Arg
40+
public class Index : Function2Arg, Function3Arg, Function4Arg, IArrayMode
4141
{
4242

4343
public ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1)

main/SS/Formula/WorkbookEvaluator.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,11 +424,12 @@ private ValueEval EvaluateAny(IEvaluationCell srcCell, int sheetIndex,
424424
{
425425
return ErrorEval.CIRCULAR_REF_ERROR;
426426
}
427-
OperationEvaluationContext ec = new OperationEvaluationContext(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);
428427

429428
try
430429
{
431430
Ptg[] ptgs = _workbook.GetFormulaTokens(srcCell);
431+
OperationEvaluationContext ec = new OperationEvaluationContext
432+
(this, _workbook, sheetIndex, rowIndex, columnIndex, tracker);
432433
if (evalListener == null)
433434
{
434435
result = EvaluateFormula(ec, ptgs);
@@ -725,11 +726,39 @@ public ValueEval EvaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs)
725726
ValueEval[] ops = new ValueEval[numops];
726727

727728
// storing the ops in reverse order since they are popping
729+
bool areaArg = false; // whether one of the operands is an area
728730
for (int j = numops - 1; j >= 0; j--)
729731
{
730732
ValueEval p = (ValueEval)stack.Pop();
731733
ops[j] = p;
734+
if(p is AreaEval)
735+
{
736+
areaArg = true;
737+
}
732738
}
739+
bool arrayMode = false;
740+
if(areaArg)
741+
for(int ii = i; ii < iSize; ii++)
742+
{
743+
if(ptgs[ii] is FuncVarPtg)
744+
{
745+
FuncVarPtg f = (FuncVarPtg)ptgs[ii];
746+
try
747+
{
748+
Functions.Function func = FunctionEval.GetBasicFunction(f.FunctionIndex);
749+
if(func != null && func is IArrayMode) {
750+
arrayMode = true;
751+
}
752+
}
753+
catch(NotImplementedException ne)
754+
{
755+
//FunctionEval.getBasicFunction can throw NotImplementedException
756+
// if the fucntion is not yet supported.
757+
}
758+
break;
759+
}
760+
}
761+
ec.IsArraymode = arrayMode;
733762
// logDebug("Invoke " + operation + " (nAgs=" + numops + ")");
734763
opResult = OperationEvaluatorFactory.Evaluate(optg, ops, ec);
735764
}
@@ -854,7 +883,7 @@ public static ValueEval DereferenceResult(ValueEval evaluationResult, OperationE
854883
IEvaluationSheet evalSheet = ec.GetWorkbook().GetSheet(ec.SheetIndex);
855884
IEvaluationCell evalCell = evalSheet.GetCell(ec.RowIndex, ec.ColumnIndex);
856885

857-
if (evalCell.IsPartOfArrayFormulaGroup && evaluationResult is AreaEval eval)
886+
if (evalCell != null && evalCell.IsPartOfArrayFormulaGroup && evaluationResult is AreaEval eval)
858887
{
859888
value = OperandResolver.GetElementFromArray(eval, evalCell);
860889
}

ooxml/XSSF/Model/SharedStringsTable.cs

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ namespace NPOI.XSSF.Model
2626
using System.IO;
2727
using NPOI.OpenXml4Net.OPC;
2828
using System.Xml;
29+
using NPOI.Util;
30+
using NPOI.XSSF.UserModel;
31+
using NPOI.SS.UserModel;
2932
using System.Text;
3033

3134
/**
@@ -529,18 +532,28 @@ private static String GetKey(CT_Rst st)
529532
return st.XmlText;
530533
}
531534

532-
/**
533-
* Return a string item by index
534-
*
535-
* @param idx index of item to return.
536-
* @return the item at the specified position in this Shared String table.
537-
*/
535+
/// <summary>
536+
/// Return a string item by index
537+
/// </summary>
538+
/// <param name="idx">index of item to return.</param>
539+
/// <returns>the item at the specified position in this Shared String table.</returns>
540+
[Obsolete("use GetItemAt(int idx) instead. Removal at POI 4.2")]
538541
public CT_Rst GetEntryAt(int idx)
539542
{
540543
EnsureLoaded();
541544
return strings[idx];
542545
}
543546

547+
/// <summary>
548+
/// Return a string item by index
549+
/// </summary>
550+
/// <param name="idx">index of item to return.</param>
551+
/// <returns>the item at the specified position in this Shared String table.</returns>
552+
public IRichTextString GetItemAt(int idx)
553+
{
554+
return new XSSFRichTextString(strings[idx]);
555+
}
556+
544557
/**
545558
* Return an integer representing the total count of strings in the workbook. This count does not
546559
* include any numbers, it counts only the total of text strings in the workbook.
@@ -583,6 +596,8 @@ public int UniqueCount
583596
* @param st the entry to add
584597
* @return index the index of Added entry
585598
*/
599+
[Obsolete("use <code>addSharedStringItem(RichTextString string)</code> instead")]
600+
[Removal(Version = "4.2")]
586601
public int AddEntry(CT_Rst st)
587602
{
588603
EnsureLoaded();
@@ -606,11 +621,33 @@ public int AddEntry(CT_Rst st)
606621
return idx;
607622
}
608623

624+
/**
625+
* Add an entry to this Shared String table (a new value is appended to the end).
626+
*
627+
* <p>
628+
* If the Shared String table already contains this string entry, its index is returned.
629+
* Otherwise a new entry is added.
630+
* </p>
631+
*
632+
* @param string the entry to add
633+
* @since POI 4.0.0
634+
* @return index the index of added entry
635+
*/
636+
public int AddSharedStringItem(IRichTextString str)
637+
{
638+
if(!(str is XSSFRichTextString)){
639+
throw new ArgumentException("Only XSSFRichTextString argument is supported");
640+
}
641+
return AddEntry(((XSSFRichTextString) str).GetCTRst());
642+
}
643+
609644
/**
610645
* Provide low-level access to the underlying array of CT_Rst beans
611646
*
612647
* @return array of CT_Rst beans
613648
*/
649+
[Obsolete("use <code>getSharedStringItems</code> instead")]
650+
[Removal(Version = "4.2")]
614651
public IList<CT_Rst> Items
615652
{
616653
get
@@ -621,8 +658,27 @@ public IList<CT_Rst> Items
621658
}
622659

623660
/**
624-
* Write this table out as XML.
661+
* Provide access to the strings in the SharedStringsTable
625662
*
663+
* @return list of shared string instances
664+
*/
665+
public IList<IRichTextString> SharedStringItems
666+
{
667+
get
668+
{
669+
List<IRichTextString> items = new List<IRichTextString>();
670+
foreach(CT_Rst rst in strings)
671+
{
672+
items.Add(new XSSFRichTextString(rst));
673+
}
674+
return items.AsReadOnly();
675+
}
676+
}
677+
678+
/**
679+
*
680+
* this table out as XML.
681+
*
626682
* @param out The stream to write to.
627683
* @throws IOException if an error occurs while writing.
628684
*/

ooxml/XSSF/UserModel/Extensions/XSSFCellBorder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public XSSFColor GetBorderColor(BorderSide side)
137137

138138
if (borderPr != null && borderPr.IsSetColor())
139139
{
140-
XSSFColor clr = new XSSFColor(borderPr.color, _indexedColorMap);
140+
XSSFColor clr = XSSFColor.From(borderPr.color, _indexedColorMap);
141141
if (_theme != null)
142142
{
143143
_theme.InheritFromThemeAsRequired(clr);

ooxml/XSSF/UserModel/Extensions/XSSFCellFill.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public XSSFColor GetFillBackgroundColor()
5959
if (ptrn == null) return null;
6060

6161
CT_Color CT_Color = ptrn.bgColor;
62-
return CT_Color == null ? null : new XSSFColor(CT_Color, _indexedColorMap);
62+
return XSSFColor.From(CT_Color, _indexedColorMap);
6363
}
6464

6565
/**
@@ -84,7 +84,15 @@ public void SetFillBackgroundColor(int index)
8484
public void SetFillBackgroundColor(XSSFColor color)
8585
{
8686
CT_PatternFill ptrn = EnsureCTPatternFill();
87-
ptrn.bgColor = (color.GetCTColor());
87+
88+
if(color == null)
89+
{
90+
ptrn.UnsetBgColor();
91+
}
92+
else
93+
{
94+
ptrn.bgColor = (color.GetCTColor());
95+
}
8896
}
8997

9098
/**
@@ -98,7 +106,7 @@ public XSSFColor GetFillForegroundColor()
98106
if (ptrn == null) return null;
99107

100108
CT_Color ctColor = ptrn.fgColor;
101-
return ctColor == null ? null : new XSSFColor(ctColor, _indexedColorMap);
109+
return XSSFColor.From(ctColor, _indexedColorMap);
102110
}
103111

104112
/**
@@ -121,7 +129,15 @@ public void SetFillForegroundColor(int index)
121129
public void SetFillForegroundColor(XSSFColor color)
122130
{
123131
CT_PatternFill ptrn = EnsureCTPatternFill();
124-
ptrn.fgColor = color.GetCTColor();
132+
133+
if(color == null)
134+
{
135+
ptrn.UnsetFgColor();
136+
}
137+
else
138+
{
139+
ptrn.fgColor = color.GetCTColor();
140+
}
125141
}
126142

127143
/**

ooxml/XSSF/UserModel/XSSFBorderFormatting.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ private static short GetIndexedColor(XSSFColor color)
436436

437437
private XSSFColor GetColor(CT_BorderPr pr)
438438
{
439-
return pr == null ? null : new XSSFColor(pr.color, _colorMap);
439+
return pr == null ? null : XSSFColor.From(pr.color, _colorMap);
440440
}
441441
#endregion
442442
}

0 commit comments

Comments
 (0)