calc.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. // Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
  2. // this source code is governed by a BSD-style license that can be found in
  3. // the LICENSE file.
  4. //
  5. // Package excelize providing a set of functions that allow you to write to
  6. // and read from XLSX / XLSM / XLTM files. Supports reading and writing
  7. // spreadsheet documents generated by Microsoft Exce™ 2007 and later. Supports
  8. // complex components by high compatibility, and provided streaming API for
  9. // generating or reading data from a worksheet with huge amounts of data. This
  10. // library needs Go version 1.10 or later.
  11. package excelize
  12. import (
  13. "container/list"
  14. "errors"
  15. "fmt"
  16. "math"
  17. "reflect"
  18. "strconv"
  19. "strings"
  20. "github.com/xuri/efp"
  21. )
  22. // Excel formula errors
  23. const (
  24. formulaErrorDIV = "#DIV/0!"
  25. formulaErrorNAME = "#NAME?"
  26. formulaErrorNA = "#N/A"
  27. formulaErrorNUM = "#NUM!"
  28. formulaErrorVALUE = "#VALUE!"
  29. formulaErrorREF = "#REF!"
  30. formulaErrorNULL = "#NULL"
  31. formulaErrorSPILL = "#SPILL!"
  32. formulaErrorCALC = "#CALC!"
  33. formulaErrorGETTINGDATA = "#GETTING_DATA"
  34. )
  35. // cellRef defines the structure of a cell reference
  36. type cellRef struct {
  37. Col int
  38. Row int
  39. Sheet string
  40. }
  41. // cellRef defines the structure of a cell range
  42. type cellRange struct {
  43. From cellRef
  44. To cellRef
  45. }
  46. type formulaFuncs struct{}
  47. // CalcCellValue provides a function to get calculated cell value. This
  48. // feature is currently in beta. Array formula, table formula and some other
  49. // formulas are not supported currently.
  50. func (f *File) CalcCellValue(sheet, cell string) (result string, err error) {
  51. var (
  52. formula string
  53. token efp.Token
  54. )
  55. if formula, err = f.GetCellFormula(sheet, cell); err != nil {
  56. return
  57. }
  58. ps := efp.ExcelParser()
  59. tokens := ps.Parse(formula)
  60. if tokens == nil {
  61. return
  62. }
  63. if token, err = f.evalInfixExp(sheet, tokens); err != nil {
  64. return
  65. }
  66. result = token.TValue
  67. return
  68. }
  69. // getPriority calculate arithmetic operator priority.
  70. func getPriority(token efp.Token) (pri int) {
  71. var priority = map[string]int{
  72. "*": 2,
  73. "/": 2,
  74. "+": 1,
  75. "-": 1,
  76. }
  77. pri, _ = priority[token.TValue]
  78. if token.TValue == "-" && token.TType == efp.TokenTypeOperatorPrefix {
  79. pri = 3
  80. }
  81. if token.TSubType == efp.TokenSubTypeStart && token.TType == efp.TokenTypeSubexpression { // (
  82. pri = 0
  83. }
  84. return
  85. }
  86. // evalInfixExp evaluate syntax analysis by given infix expression after
  87. // lexical analysis. Evaluate an infix expression containing formulas by
  88. // stacks:
  89. //
  90. // opd - Operand
  91. // opt - Operator
  92. // opf - Operation formula
  93. // opfd - Operand of the operation formula
  94. // opft - Operator of the operation formula
  95. // args - Arguments of the operation formula
  96. //
  97. func (f *File) evalInfixExp(sheet string, tokens []efp.Token) (efp.Token, error) {
  98. var err error
  99. opdStack, optStack, opfStack, opfdStack, opftStack, argsStack := NewStack(), NewStack(), NewStack(), NewStack(), NewStack(), NewStack()
  100. for i := 0; i < len(tokens); i++ {
  101. token := tokens[i]
  102. // out of function stack
  103. if opfStack.Len() == 0 {
  104. if err = f.parseToken(sheet, token, opdStack, optStack); err != nil {
  105. return efp.Token{}, err
  106. }
  107. }
  108. // function start
  109. if token.TType == efp.TokenTypeFunction && token.TSubType == efp.TokenSubTypeStart {
  110. opfStack.Push(token)
  111. continue
  112. }
  113. // in function stack, walk 2 token at once
  114. if opfStack.Len() > 0 {
  115. var nextToken efp.Token
  116. if i+1 < len(tokens) {
  117. nextToken = tokens[i+1]
  118. }
  119. // current token is args or range, skip next token, order required: parse reference first
  120. if token.TSubType == efp.TokenSubTypeRange {
  121. if !opftStack.Empty() {
  122. // parse reference: must reference at here
  123. result, err := f.parseReference(sheet, token.TValue)
  124. if err != nil {
  125. return efp.Token{TValue: formulaErrorNAME}, err
  126. }
  127. if len(result) != 1 {
  128. return efp.Token{}, errors.New(formulaErrorVALUE)
  129. }
  130. opfdStack.Push(efp.Token{
  131. TType: efp.TokenTypeOperand,
  132. TSubType: efp.TokenSubTypeNumber,
  133. TValue: result[0],
  134. })
  135. continue
  136. }
  137. if nextToken.TType == efp.TokenTypeArgument || nextToken.TType == efp.TokenTypeFunction {
  138. // parse reference: reference or range at here
  139. result, err := f.parseReference(sheet, token.TValue)
  140. if err != nil {
  141. return efp.Token{TValue: formulaErrorNAME}, err
  142. }
  143. for _, val := range result {
  144. argsStack.Push(efp.Token{
  145. TType: efp.TokenTypeOperand,
  146. TSubType: efp.TokenSubTypeNumber,
  147. TValue: val,
  148. })
  149. }
  150. if len(result) == 0 {
  151. return efp.Token{}, errors.New(formulaErrorVALUE)
  152. }
  153. continue
  154. }
  155. }
  156. // check current token is opft
  157. if err = f.parseToken(sheet, token, opfdStack, opftStack); err != nil {
  158. return efp.Token{}, err
  159. }
  160. // current token is arg
  161. if token.TType == efp.TokenTypeArgument {
  162. for !opftStack.Empty() {
  163. // calculate trigger
  164. topOpt := opftStack.Peek().(efp.Token)
  165. if err := calculate(opfdStack, topOpt); err != nil {
  166. return efp.Token{}, err
  167. }
  168. opftStack.Pop()
  169. }
  170. if !opfdStack.Empty() {
  171. argsStack.Push(opfdStack.Pop())
  172. }
  173. continue
  174. }
  175. // current token is function stop
  176. if token.TType == efp.TokenTypeFunction && token.TSubType == efp.TokenSubTypeStop {
  177. for !opftStack.Empty() {
  178. // calculate trigger
  179. topOpt := opftStack.Peek().(efp.Token)
  180. if err := calculate(opfdStack, topOpt); err != nil {
  181. return efp.Token{}, err
  182. }
  183. opftStack.Pop()
  184. }
  185. // push opfd to args
  186. if opfdStack.Len() > 0 {
  187. argsStack.Push(opfdStack.Pop())
  188. }
  189. // call formula function to evaluate
  190. result, err := callFuncByName(&formulaFuncs{}, opfStack.Peek().(efp.Token).TValue, []reflect.Value{reflect.ValueOf(argsStack)})
  191. if err != nil {
  192. return efp.Token{}, err
  193. }
  194. opfStack.Pop()
  195. if opfStack.Len() > 0 { // still in function stack
  196. opfdStack.Push(efp.Token{TValue: result, TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  197. } else {
  198. opdStack.Push(efp.Token{TValue: result, TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  199. }
  200. }
  201. }
  202. }
  203. for optStack.Len() != 0 {
  204. topOpt := optStack.Peek().(efp.Token)
  205. if err = calculate(opdStack, topOpt); err != nil {
  206. return efp.Token{}, err
  207. }
  208. optStack.Pop()
  209. }
  210. return opdStack.Peek().(efp.Token), err
  211. }
  212. // calculate evaluate basic arithmetic operations.
  213. func calculate(opdStack *Stack, opt efp.Token) error {
  214. if opt.TValue == "-" && opt.TType == efp.TokenTypeOperatorPrefix {
  215. opd := opdStack.Pop().(efp.Token)
  216. opdVal, err := strconv.ParseFloat(opd.TValue, 64)
  217. if err != nil {
  218. return err
  219. }
  220. result := 0 - opdVal
  221. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  222. }
  223. if opt.TValue == "+" {
  224. rOpd := opdStack.Pop().(efp.Token)
  225. lOpd := opdStack.Pop().(efp.Token)
  226. lOpdVal, err := strconv.ParseFloat(lOpd.TValue, 64)
  227. if err != nil {
  228. return err
  229. }
  230. rOpdVal, err := strconv.ParseFloat(rOpd.TValue, 64)
  231. if err != nil {
  232. return err
  233. }
  234. result := lOpdVal + rOpdVal
  235. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  236. }
  237. if opt.TValue == "-" && opt.TType == efp.TokenTypeOperatorInfix {
  238. rOpd := opdStack.Pop().(efp.Token)
  239. lOpd := opdStack.Pop().(efp.Token)
  240. lOpdVal, err := strconv.ParseFloat(lOpd.TValue, 64)
  241. if err != nil {
  242. return err
  243. }
  244. rOpdVal, err := strconv.ParseFloat(rOpd.TValue, 64)
  245. if err != nil {
  246. return err
  247. }
  248. result := lOpdVal - rOpdVal
  249. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  250. }
  251. if opt.TValue == "*" {
  252. rOpd := opdStack.Pop().(efp.Token)
  253. lOpd := opdStack.Pop().(efp.Token)
  254. lOpdVal, err := strconv.ParseFloat(lOpd.TValue, 64)
  255. if err != nil {
  256. return err
  257. }
  258. rOpdVal, err := strconv.ParseFloat(rOpd.TValue, 64)
  259. if err != nil {
  260. return err
  261. }
  262. result := lOpdVal * rOpdVal
  263. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  264. }
  265. if opt.TValue == "/" {
  266. rOpd := opdStack.Pop().(efp.Token)
  267. lOpd := opdStack.Pop().(efp.Token)
  268. lOpdVal, err := strconv.ParseFloat(lOpd.TValue, 64)
  269. if err != nil {
  270. return err
  271. }
  272. rOpdVal, err := strconv.ParseFloat(rOpd.TValue, 64)
  273. if err != nil {
  274. return err
  275. }
  276. result := lOpdVal / rOpdVal
  277. if rOpdVal == 0 {
  278. return errors.New(formulaErrorDIV)
  279. }
  280. opdStack.Push(efp.Token{TValue: fmt.Sprintf("%g", result), TType: efp.TokenTypeOperand, TSubType: efp.TokenSubTypeNumber})
  281. }
  282. return nil
  283. }
  284. // parseToken parse basic arithmetic operator priority and evaluate based on
  285. // operators and operands.
  286. func (f *File) parseToken(sheet string, token efp.Token, opdStack, optStack *Stack) error {
  287. // parse reference: must reference at here
  288. if token.TSubType == efp.TokenSubTypeRange {
  289. result, err := f.parseReference(sheet, token.TValue)
  290. if err != nil {
  291. return errors.New(formulaErrorNAME)
  292. }
  293. if len(result) != 1 {
  294. return errors.New(formulaErrorVALUE)
  295. }
  296. token.TValue = result[0]
  297. token.TType = efp.TokenTypeOperand
  298. token.TSubType = efp.TokenSubTypeNumber
  299. }
  300. if (token.TValue == "-" && token.TType == efp.TokenTypeOperatorPrefix) || token.TValue == "+" || token.TValue == "-" || token.TValue == "*" || token.TValue == "/" {
  301. if optStack.Len() == 0 {
  302. optStack.Push(token)
  303. } else {
  304. tokenPriority := getPriority(token)
  305. topOpt := optStack.Peek().(efp.Token)
  306. topOptPriority := getPriority(topOpt)
  307. if tokenPriority > topOptPriority {
  308. optStack.Push(token)
  309. } else {
  310. for tokenPriority <= topOptPriority {
  311. optStack.Pop()
  312. if err := calculate(opdStack, topOpt); err != nil {
  313. return err
  314. }
  315. if optStack.Len() > 0 {
  316. topOpt = optStack.Peek().(efp.Token)
  317. topOptPriority = getPriority(topOpt)
  318. continue
  319. }
  320. break
  321. }
  322. optStack.Push(token)
  323. }
  324. }
  325. }
  326. if token.TType == efp.TokenTypeSubexpression && token.TSubType == efp.TokenSubTypeStart { // (
  327. optStack.Push(token)
  328. }
  329. if token.TType == efp.TokenTypeSubexpression && token.TSubType == efp.TokenSubTypeStop { // )
  330. for optStack.Peek().(efp.Token).TSubType != efp.TokenSubTypeStart && optStack.Peek().(efp.Token).TType != efp.TokenTypeSubexpression { // != (
  331. topOpt := optStack.Peek().(efp.Token)
  332. if err := calculate(opdStack, topOpt); err != nil {
  333. return err
  334. }
  335. optStack.Pop()
  336. }
  337. optStack.Pop()
  338. }
  339. // opd
  340. if token.TType == efp.TokenTypeOperand && token.TSubType == efp.TokenSubTypeNumber {
  341. opdStack.Push(token)
  342. }
  343. return nil
  344. }
  345. // parseReference parse reference and extract values by given reference
  346. // characters and default sheet name.
  347. func (f *File) parseReference(sheet, reference string) (result []string, err error) {
  348. reference = strings.Replace(reference, "$", "", -1)
  349. refs, cellRanges, cellRefs := list.New(), list.New(), list.New()
  350. for _, ref := range strings.Split(reference, ":") {
  351. tokens := strings.Split(ref, "!")
  352. cr := cellRef{}
  353. if len(tokens) == 2 { // have a worksheet name
  354. cr.Sheet = tokens[0]
  355. if cr.Col, cr.Row, err = CellNameToCoordinates(tokens[1]); err != nil {
  356. return
  357. }
  358. if refs.Len() > 0 {
  359. e := refs.Back()
  360. cellRefs.PushBack(e.Value.(cellRef))
  361. refs.Remove(e)
  362. }
  363. refs.PushBack(cr)
  364. continue
  365. }
  366. if cr.Col, cr.Row, err = CellNameToCoordinates(tokens[0]); err != nil {
  367. return
  368. }
  369. e := refs.Back()
  370. if e == nil {
  371. cr.Sheet = sheet
  372. refs.PushBack(cr)
  373. continue
  374. }
  375. cellRanges.PushBack(cellRange{
  376. From: e.Value.(cellRef),
  377. To: cr,
  378. })
  379. refs.Remove(e)
  380. }
  381. if refs.Len() > 0 {
  382. e := refs.Back()
  383. cellRefs.PushBack(e.Value.(cellRef))
  384. refs.Remove(e)
  385. }
  386. result, err = f.rangeResolver(cellRefs, cellRanges)
  387. return
  388. }
  389. // rangeResolver extract value as string from given reference and range list.
  390. // This function will not ignore the empty cell. Note that the result of 3D
  391. // range references may be different from Excel in some cases, for example,
  392. // A1:A2:A2:B3 in Excel will include B2, but we wont.
  393. func (f *File) rangeResolver(cellRefs, cellRanges *list.List) (result []string, err error) {
  394. filter := map[string]string{}
  395. // extract value from ranges
  396. for temp := cellRanges.Front(); temp != nil; temp = temp.Next() {
  397. cr := temp.Value.(cellRange)
  398. if cr.From.Sheet != cr.To.Sheet {
  399. err = errors.New(formulaErrorVALUE)
  400. }
  401. rng := []int{cr.From.Col, cr.From.Row, cr.To.Col, cr.To.Row}
  402. sortCoordinates(rng)
  403. for col := rng[0]; col <= rng[2]; col++ {
  404. for row := rng[1]; row <= rng[3]; row++ {
  405. var cell string
  406. if cell, err = CoordinatesToCellName(col, row); err != nil {
  407. return
  408. }
  409. if filter[cell], err = f.GetCellValue(cr.From.Sheet, cell); err != nil {
  410. return
  411. }
  412. }
  413. }
  414. }
  415. // extract value from references
  416. for temp := cellRefs.Front(); temp != nil; temp = temp.Next() {
  417. cr := temp.Value.(cellRef)
  418. var cell string
  419. if cell, err = CoordinatesToCellName(cr.Col, cr.Row); err != nil {
  420. return
  421. }
  422. if filter[cell], err = f.GetCellValue(cr.Sheet, cell); err != nil {
  423. return
  424. }
  425. }
  426. for _, val := range filter {
  427. result = append(result, val)
  428. }
  429. return
  430. }
  431. // callFuncByName calls the no error or only error return function with
  432. // reflect by given receiver, name and parameters.
  433. func callFuncByName(receiver interface{}, name string, params []reflect.Value) (result string, err error) {
  434. function := reflect.ValueOf(receiver).MethodByName(name)
  435. if function.IsValid() {
  436. rt := function.Call(params)
  437. if len(rt) == 0 {
  438. return
  439. }
  440. if !rt[1].IsNil() {
  441. err = rt[1].Interface().(error)
  442. return
  443. }
  444. result = rt[0].Interface().(string)
  445. return
  446. }
  447. err = fmt.Errorf("not support %s function", name)
  448. return
  449. }
  450. // Math and Trigonometric functions
  451. // SUM function adds together a supplied set of numbers and returns the sum of
  452. // these values. The syntax of the function is:
  453. //
  454. // SUM(number1,[number2],...)
  455. //
  456. func (fn *formulaFuncs) SUM(argsStack *Stack) (result string, err error) {
  457. var val float64
  458. var sum float64
  459. for !argsStack.Empty() {
  460. token := argsStack.Pop().(efp.Token)
  461. if token.TValue == "" {
  462. continue
  463. }
  464. val, err = strconv.ParseFloat(token.TValue, 64)
  465. if err != nil {
  466. return
  467. }
  468. sum += val
  469. }
  470. result = fmt.Sprintf("%g", sum)
  471. return
  472. }
  473. // PRODUCT function returns the product (multiplication) of a supplied set of numerical values.
  474. // The syntax of the function is:
  475. //
  476. // PRODUCT(number1,[number2],...)
  477. //
  478. func (fn *formulaFuncs) PRODUCT(argsStack *Stack) (result string, err error) {
  479. var (
  480. val float64
  481. product float64 = 1
  482. )
  483. for !argsStack.Empty() {
  484. token := argsStack.Pop().(efp.Token)
  485. if token.TValue == "" {
  486. continue
  487. }
  488. val, err = strconv.ParseFloat(token.TValue, 64)
  489. if err != nil {
  490. return
  491. }
  492. product = product * val
  493. }
  494. result = fmt.Sprintf("%g", product)
  495. return
  496. }
  497. // PRODUCT function calculates a given number, raised to a supplied power.
  498. // The syntax of the function is:
  499. //
  500. // POWER(number,power)
  501. //
  502. func (fn *formulaFuncs) POWER(argsStack *Stack) (result string, err error) {
  503. if argsStack.Len() != 2 {
  504. err = errors.New("POWER requires 2 numeric arguments")
  505. return
  506. }
  507. var x, y float64
  508. y, err = strconv.ParseFloat(argsStack.Pop().(efp.Token).TValue, 64)
  509. if err != nil {
  510. return
  511. }
  512. x, err = strconv.ParseFloat(argsStack.Pop().(efp.Token).TValue, 64)
  513. if err != nil {
  514. return
  515. }
  516. if x == 0 && y == 0 {
  517. err = errors.New(formulaErrorNUM)
  518. return
  519. }
  520. if x == 0 && y < 0 {
  521. err = errors.New(formulaErrorDIV)
  522. return
  523. }
  524. result = fmt.Sprintf("%g", math.Pow(x, y))
  525. return
  526. }
  527. // SQRT function calculates the positive square root of a supplied number.
  528. // The syntax of the function is:
  529. //
  530. // SQRT(number)
  531. //
  532. func (fn *formulaFuncs) SQRT(argsStack *Stack) (result string, err error) {
  533. if argsStack.Len() != 1 {
  534. err = errors.New("SQRT requires 1 numeric arguments")
  535. return
  536. }
  537. var val float64
  538. val, err = strconv.ParseFloat(argsStack.Pop().(efp.Token).TValue, 64)
  539. if err != nil {
  540. return
  541. }
  542. if val < 0 {
  543. err = errors.New(formulaErrorNUM)
  544. return
  545. }
  546. result = fmt.Sprintf("%g", math.Sqrt(val))
  547. return
  548. }
  549. // QUOTIENT function returns the integer portion of a division between two supplied numbers.
  550. // The syntax of the function is:
  551. //
  552. // QUOTIENT(numerator,denominator)
  553. //
  554. func (fn *formulaFuncs) QUOTIENT(argsStack *Stack) (result string, err error) {
  555. if argsStack.Len() != 2 {
  556. err = errors.New("QUOTIENT requires 2 numeric arguments")
  557. return
  558. }
  559. var x, y float64
  560. y, err = strconv.ParseFloat(argsStack.Pop().(efp.Token).TValue, 64)
  561. if err != nil {
  562. return
  563. }
  564. x, err = strconv.ParseFloat(argsStack.Pop().(efp.Token).TValue, 64)
  565. if err != nil {
  566. return
  567. }
  568. if y == 0 {
  569. err = errors.New(formulaErrorDIV)
  570. return
  571. }
  572. result = fmt.Sprintf("%g", math.Trunc(x/y))
  573. return
  574. }