Skip to content

Commit 121ac17

Browse files
committed
This fixed incorrect formula calculation exception expected result
- Simplify and remove duplicate code for optimization - Update documentation comments with typo fix - Handle error return to save the workbook - Add file path length limitation details in the error message
1 parent e3fb2d7 commit 121ac17

16 files changed

+209
-317
lines changed

calc.go

+126-187
Large diffs are not rendered by default.

calc_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -4334,9 +4334,9 @@ func TestCalcCellValue(t *testing.T) {
43344334
"=YIELD(\"01/01/2010\",\"06/30/2015\",10%,101,100,4,\"\")": {"#NUM!", "#NUM!"},
43354335
"=YIELD(\"01/01/2010\",\"06/30/2015\",10%,101,100,3)": {"#NUM!", "#NUM!"},
43364336
"=YIELD(\"01/01/2010\",\"06/30/2015\",10%,101,100,4,5)": {"#NUM!", "invalid basis"},
4337-
"=YIELD(\"01/01/2010\",\"06/30/2015\",-1,101,100,4)": {"#NUM!", "PRICE requires rate >= 0"},
4338-
"=YIELD(\"01/01/2010\",\"06/30/2015\",10%,0,100,4)": {"#NUM!", "PRICE requires pr > 0"},
4339-
"=YIELD(\"01/01/2010\",\"06/30/2015\",10%,101,-1,4)": {"#NUM!", "PRICE requires redemption >= 0"},
4337+
"=YIELD(\"01/01/2010\",\"06/30/2015\",-1,101,100,4)": {"#NUM!", "YIELD requires rate >= 0"},
4338+
"=YIELD(\"01/01/2010\",\"06/30/2015\",10%,0,100,4)": {"#NUM!", "YIELD requires pr > 0"},
4339+
"=YIELD(\"01/01/2010\",\"06/30/2015\",10%,101,-1,4)": {"#NUM!", "YIELD requires redemption >= 0"},
43404340
// YIELDDISC
43414341
"=YIELDDISC()": {"#VALUE!", "YIELDDISC requires 4 or 5 arguments"},
43424342
"=YIELDDISC(\"\",\"06/30/2017\",97,100,0)": {"#VALUE!", "#VALUE!"},

date.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func julianDateToGregorianTime(part1, part2 float64) time.Time {
114114
// "Communications of the ACM" in 1968 (published in CACM, volume 11, number
115115
// 10, October 1968, p.657). None of those programmers seems to have found it
116116
// necessary to explain the constants or variable names set out by Henry F.
117-
// Fliegel and Thomas C. Van Flandern. Maybe one day I'll buy that jounal and
117+
// Fliegel and Thomas C. Van Flandern. Maybe one day I'll buy that journal and
118118
// expand an explanation here - that day is not today.
119119
func doTheFliegelAndVanFlandernAlgorithm(jd int) (day, month, year int) {
120120
l := jd + 68569
@@ -163,7 +163,7 @@ func timeFromExcelTime(excelTime float64, date1904 bool) time.Time {
163163
return date.Truncate(time.Second)
164164
}
165165

166-
// ExcelDateToTime converts a float-based excel date representation to a time.Time.
166+
// ExcelDateToTime converts a float-based Excel date representation to a time.Time.
167167
func ExcelDateToTime(excelDate float64, use1904Format bool) (time.Time, error) {
168168
if excelDate < 0 {
169169
return time.Time{}, newInvalidExcelDateError(excelDate)

errors.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ var (
143143
ErrWorkbookFileFormat = errors.New("unsupported workbook file format")
144144
// ErrMaxFilePathLength defined the error message on receive the file path
145145
// length overflow.
146-
ErrMaxFilePathLength = errors.New("file path length exceeds maximum limit")
146+
ErrMaxFilePathLength = fmt.Errorf("file path length exceeds maximum limit %d characters", MaxFilePathLength)
147147
// ErrUnknownEncryptMechanism defined the error message on unsupported
148148
// encryption mechanism.
149149
ErrUnknownEncryptMechanism = errors.New("unknown encryption mechanism")

excelize.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ type File struct {
6060
// the spreadsheet from non-UTF-8 encoding.
6161
type charsetTranscoderFn func(charset string, input io.Reader) (rdr io.Reader, err error)
6262

63-
// Options define the options for o`pen and reading spreadsheet.
63+
// Options define the options for opening and reading the spreadsheet.
6464
//
6565
// MaxCalcIterations specifies the maximum iterations for iterative
6666
// calculation, the default value is 0.
@@ -70,7 +70,7 @@ type charsetTranscoderFn func(charset string, input io.Reader) (rdr io.Reader, e
7070
// RawCellValue specifies if apply the number format for the cell value or get
7171
// the raw value.
7272
//
73-
// UnzipSizeLimit specifies the unzip size limit in bytes on open the
73+
// UnzipSizeLimit specifies to unzip size limit in bytes on open the
7474
// spreadsheet, this value should be greater than or equal to
7575
// UnzipXMLSizeLimit, the default size limit is 16GB.
7676
//
@@ -106,7 +106,7 @@ type Options struct {
106106
CultureInfo CultureName
107107
}
108108

109-
// OpenFile take the name of an spreadsheet file and returns a populated
109+
// OpenFile take the name of a spreadsheet file and returns a populated
110110
// spreadsheet file struct for it. For example, open spreadsheet with
111111
// password protection:
112112
//

hsl.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func hslModel(c color.Color) color.Color {
6060
return HSL{h, s, l}
6161
}
6262

63-
// RGBToHSL converts an RGB triple to a HSL triple.
63+
// RGBToHSL converts an RGB triple to an HSL triple.
6464
func RGBToHSL(r, g, b uint8) (h, s, l float64) {
6565
fR := float64(r) / 255
6666
fG := float64(g) / 255
@@ -95,7 +95,7 @@ func RGBToHSL(r, g, b uint8) (h, s, l float64) {
9595
return
9696
}
9797

98-
// HSLToRGB converts an HSL triple to a RGB triple.
98+
// HSLToRGB converts an HSL triple to an RGB triple.
9999
func HSLToRGB(h, s, l float64) (r, g, b uint8) {
100100
var fR, fG, fB float64
101101
if s == 0 {

numfmt.go

+19-19
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,7 @@ func getNumberPartLen(n float64) (int, int) {
11361136
return len(parts[0]), 0
11371137
}
11381138

1139-
// getNumberFmtConf generate the number format padding and place holder
1139+
// getNumberFmtConf generate the number format padding and placeholder
11401140
// configurations.
11411141
func (nf *numberFormat) getNumberFmtConf() {
11421142
for _, token := range nf.section[nf.sectionIdx].Items {
@@ -1183,9 +1183,9 @@ func (nf *numberFormat) printNumberLiteral(text string) string {
11831183
if nf.usePositive {
11841184
result += "-"
11851185
}
1186-
for i, token := range nf.section[nf.sectionIdx].Items {
1186+
for _, token := range nf.section[nf.sectionIdx].Items {
11871187
if token.TType == nfp.TokenTypeCurrencyLanguage {
1188-
if err, changeNumFmtCode := nf.currencyLanguageHandler(i, token); err != nil || changeNumFmtCode {
1188+
if err, changeNumFmtCode := nf.currencyLanguageHandler(token); err != nil || changeNumFmtCode {
11891189
return nf.value
11901190
}
11911191
result += nf.currencyString
@@ -1321,7 +1321,7 @@ func (nf *numberFormat) dateTimeHandler() string {
13211321
nf.t, nf.hours, nf.seconds = timeFromExcelTime(nf.number, nf.date1904), false, false
13221322
for i, token := range nf.section[nf.sectionIdx].Items {
13231323
if token.TType == nfp.TokenTypeCurrencyLanguage {
1324-
if err, changeNumFmtCode := nf.currencyLanguageHandler(i, token); err != nil || changeNumFmtCode {
1324+
if err, changeNumFmtCode := nf.currencyLanguageHandler(token); err != nil || changeNumFmtCode {
13251325
return nf.value
13261326
}
13271327
nf.result += nf.currencyString
@@ -1392,7 +1392,7 @@ func (nf *numberFormat) positiveHandler() string {
13921392

13931393
// currencyLanguageHandler will be handling currency and language types tokens
13941394
// for a number format expression.
1395-
func (nf *numberFormat) currencyLanguageHandler(i int, token nfp.Token) (error, bool) {
1395+
func (nf *numberFormat) currencyLanguageHandler(token nfp.Token) (error, bool) {
13961396
for _, part := range token.Parts {
13971397
if inStrSlice(supportedTokenTypes, part.Token.TType, true) == -1 {
13981398
return ErrUnsupportedNumberFormat, false
@@ -1491,7 +1491,7 @@ func localMonthsNameFrench(t time.Time, abbr int) string {
14911491
// localMonthsNameIrish returns the Irish name of the month.
14921492
func localMonthsNameIrish(t time.Time, abbr int) string {
14931493
if abbr == 3 {
1494-
return monthNamesIrishAbbr[int(t.Month()-1)]
1494+
return monthNamesIrishAbbr[(t.Month() - 1)]
14951495
}
14961496
if abbr == 4 {
14971497
return monthNamesIrish[int(t.Month())-1]
@@ -1524,7 +1524,7 @@ func localMonthsNameGerman(t time.Time, abbr int) string {
15241524
// localMonthsNameChinese1 returns the Chinese name of the month.
15251525
func localMonthsNameChinese1(t time.Time, abbr int) string {
15261526
if abbr == 3 {
1527-
return monthNamesChineseAbbrPlus[int(t.Month())]
1527+
return monthNamesChineseAbbrPlus[t.Month()]
15281528
}
15291529
if abbr == 4 {
15301530
return monthNamesChinesePlus[int(t.Month())-1]
@@ -1543,15 +1543,15 @@ func localMonthsNameChinese2(t time.Time, abbr int) string {
15431543
// localMonthsNameChinese3 returns the Chinese name of the month.
15441544
func localMonthsNameChinese3(t time.Time, abbr int) string {
15451545
if abbr == 3 || abbr == 4 {
1546-
return monthNamesChineseAbbrPlus[int(t.Month())]
1546+
return monthNamesChineseAbbrPlus[t.Month()]
15471547
}
15481548
return strconv.Itoa(int(t.Month()))
15491549
}
15501550

15511551
// localMonthsNameKorean returns the Korean name of the month.
15521552
func localMonthsNameKorean(t time.Time, abbr int) string {
15531553
if abbr == 3 || abbr == 4 {
1554-
return monthNamesKoreanAbbrPlus[int(t.Month())]
1554+
return monthNamesKoreanAbbrPlus[t.Month()]
15551555
}
15561556
return strconv.Itoa(int(t.Month()))
15571557
}
@@ -1562,7 +1562,7 @@ func localMonthsNameTraditionalMongolian(t time.Time, abbr int) string {
15621562
if abbr == 5 {
15631563
return "M"
15641564
}
1565-
return monthNamesTradMongolian[int(t.Month()-1)]
1565+
return monthNamesTradMongolian[t.Month()-1]
15661566
}
15671567

15681568
// localMonthsNameRussian returns the Russian name of the month.
@@ -1642,12 +1642,12 @@ func localMonthsNameWelsh(t time.Time, abbr int) string {
16421642
// localMonthsNameVietnamese returns the Vietnamese name of the month.
16431643
func localMonthsNameVietnamese(t time.Time, abbr int) string {
16441644
if abbr == 3 {
1645-
return monthNamesVietnameseAbbr3[int(t.Month()-1)]
1645+
return monthNamesVietnameseAbbr3[t.Month()-1]
16461646
}
16471647
if abbr == 5 {
1648-
return monthNamesVietnameseAbbr5[int(t.Month()-1)]
1648+
return monthNamesVietnameseAbbr5[t.Month()-1]
16491649
}
1650-
return monthNamesVietnamese[int(t.Month()-1)]
1650+
return monthNamesVietnamese[t.Month()-1]
16511651
}
16521652

16531653
// localMonthsNameWolof returns the Wolof name of the month.
@@ -1675,15 +1675,15 @@ func localMonthsNameXhosa(t time.Time, abbr int) string {
16751675
// localMonthsNameYi returns the Yi name of the month.
16761676
func localMonthsNameYi(t time.Time, abbr int) string {
16771677
if abbr == 3 || abbr == 4 {
1678-
return monthNamesYiSuffix[int(t.Month()-1)]
1678+
return monthNamesYiSuffix[t.Month()-1]
16791679
}
16801680
return string([]rune(monthNamesYi[int(t.Month())-1])[:1])
16811681
}
16821682

16831683
// localMonthsNameZulu returns the Zulu name of the month.
16841684
func localMonthsNameZulu(t time.Time, abbr int) string {
16851685
if abbr == 3 {
1686-
return monthNamesZuluAbbr[int(t.Month()-1)]
1686+
return monthNamesZuluAbbr[t.Month()-1]
16871687
}
16881688
if abbr == 4 {
16891689
return monthNamesZulu[int(t.Month())-1]
@@ -1737,16 +1737,16 @@ func (nf *numberFormat) dateTimesHandler(i int, token nfp.Token) {
17371737
return
17381738
}
17391739
}
1740-
nf.yearsHandler(i, token)
1741-
nf.daysHandler(i, token)
1740+
nf.yearsHandler(token)
1741+
nf.daysHandler(token)
17421742
nf.hoursHandler(i, token)
17431743
nf.minutesHandler(token)
17441744
nf.secondsHandler(token)
17451745
}
17461746

17471747
// yearsHandler will be handling years in the date and times types tokens for a
17481748
// number format expression.
1749-
func (nf *numberFormat) yearsHandler(i int, token nfp.Token) {
1749+
func (nf *numberFormat) yearsHandler(token nfp.Token) {
17501750
years := strings.Contains(strings.ToUpper(token.TValue), "Y")
17511751
if years && len(token.TValue) <= 2 {
17521752
nf.result += strconv.Itoa(nf.t.Year())[2:]
@@ -1760,7 +1760,7 @@ func (nf *numberFormat) yearsHandler(i int, token nfp.Token) {
17601760

17611761
// daysHandler will be handling days in the date and times types tokens for a
17621762
// number format expression.
1763-
func (nf *numberFormat) daysHandler(i int, token nfp.Token) {
1763+
func (nf *numberFormat) daysHandler(token nfp.Token) {
17641764
if strings.Contains(strings.ToUpper(token.TValue), "D") {
17651765
switch len(token.TValue) {
17661766
case 1:

numfmt_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,7 @@ func TestNumFmt(t *testing.T) {
10931093
}
10941094
}
10951095
nf := numberFormat{}
1096-
err, changeNumFmtCode := nf.currencyLanguageHandler(0, nfp.Token{Parts: []nfp.Part{{}}})
1096+
err, changeNumFmtCode := nf.currencyLanguageHandler(nfp.Token{Parts: []nfp.Part{{}}})
10971097
assert.Equal(t, ErrUnsupportedNumberFormat, err)
10981098
assert.False(t, changeNumFmtCode)
10991099
}

rows.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ type Rows struct {
7979
curRowOpts, seekRowOpts RowOpts
8080
}
8181

82-
// Next will return true if find the next row element.
82+
// Next will return true if it finds the next row element.
8383
func (rows *Rows) Next() bool {
8484
rows.seekRow++
8585
if rows.curRow >= rows.seekRow {
@@ -297,7 +297,9 @@ func (f *File) getFromStringItem(index int) string {
297297
}
298298
needClose, decoder, tempFile, err := f.xmlDecoder(defaultXMLPathSharedStrings)
299299
if needClose && err == nil {
300-
defer tempFile.Close()
300+
defer func() {
301+
err = tempFile.Close()
302+
}()
301303
}
302304
f.sharedStringItem = [][]uint{}
303305
f.sharedStringTemp, _ = os.CreateTemp(os.TempDir(), "excelize-")

0 commit comments

Comments
 (0)