Browse Source

Fixed #813, streaming data writer result missing after call normal API
#65 formula function: COMPLEX

xuri 4 years ago
parent
commit
89c262fc1d
3 changed files with 46 additions and 0 deletions
  1. 30 0
      calc.go
  2. 13 0
      calc_test.go
  3. 3 0
      file.go

+ 30 - 0
calc.go

@@ -248,6 +248,7 @@ var tokenPriority = map[string]int{
 //    COLUMNS
 //    COMBIN
 //    COMBINA
+//    COMPLEX
 //    CONCAT
 //    CONCATENATE
 //    COS
@@ -1449,6 +1450,35 @@ func (fn *formulaFuncs) bitwise(name string, argsList *list.List) formulaArg {
 	return newNumberFormulaArg(float64(bitwiseFunc(int(num1.Number), int(num2.Number))))
 }
 
+// COMPLEX function takes two arguments, representing the real and the
+// imaginary coefficients of a complex number, and from these, creates a
+// complex number. The syntax of the function is:
+//
+//    COMPLEX(real_num,i_num,[suffix])
+//
+func (fn *formulaFuncs) COMPLEX(argsList *list.List) formulaArg {
+	if argsList.Len() < 2 {
+		return newErrorFormulaArg(formulaErrorVALUE, "COMPLEX requires at least 2 arguments")
+	}
+	if argsList.Len() > 3 {
+		return newErrorFormulaArg(formulaErrorVALUE, "COMPLEX allows at most 3 arguments")
+	}
+	real, i, suffix := argsList.Front().Value.(formulaArg).ToNumber(), argsList.Front().Next().Value.(formulaArg).ToNumber(), "i"
+	if real.Type != ArgNumber {
+		return real
+	}
+	if i.Type != ArgNumber {
+		return i
+	}
+	if argsList.Len() == 3 {
+		if suffix = strings.ToLower(argsList.Back().Value.(formulaArg).Value()); suffix != "i" && suffix != "j" {
+			return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
+		}
+	}
+	r := strings.NewReplacer("(", "", ")", "", "0+", "", "+0i", "", "0+0i", "0", "i", suffix)
+	return newStringFormulaArg(r.Replace(fmt.Sprint(complex(real.Number, i.Number))))
+}
+
 // DEC2BIN function converts a decimal number into a Binary (Base 2) number.
 // The syntax of the function is:
 //

+ 13 - 0
calc_test.go

@@ -83,6 +83,13 @@ func TestCalcCellValue(t *testing.T) {
 		// BITXOR
 		"=BITXOR(5,6)":  "3",
 		"=BITXOR(9,12)": "5",
+		// COMPLEX
+		"=COMPLEX(5,2)":         "5+2i",
+		"=COMPLEX(5,-9)":        "5-9i",
+		"=COMPLEX(-1,2,\"j\")":  "-1+2j",
+		"=COMPLEX(10,-5,\"i\")": "10-5i",
+		"=COMPLEX(0,5)":         "5i",
+		"=COMPLEX(3,0)":         "3",
 		// DEC2BIN
 		"=DEC2BIN(2)":    "10",
 		"=DEC2BIN(3)":    "11",
@@ -1080,6 +1087,12 @@ func TestCalcCellValue(t *testing.T) {
 		"=BITXOR(\"\",-1)": "#NUM!",
 		"=BITXOR(1,\"\")":  "#NUM!",
 		"=BITXOR(1,2^48)":  "#NUM!",
+		// COMPLEX
+		"=COMPLEX()":              "COMPLEX requires at least 2 arguments",
+		"=COMPLEX(10,-5,\"\")":    "#VALUE!",
+		"=COMPLEX(\"\",0)":        "strconv.ParseFloat: parsing \"\": invalid syntax",
+		"=COMPLEX(0,\"\")":        "strconv.ParseFloat: parsing \"\": invalid syntax",
+		"=COMPLEX(10,-5,\"i\",0)": "COMPLEX allows at most 3 arguments",
 		// DEC2BIN
 		"=DEC2BIN()":        "DEC2BIN requires at least 1 argument",
 		"=DEC2BIN(1,1,1)":   "DEC2BIN allows at most 2 arguments",

+ 3 - 0
file.go

@@ -131,6 +131,9 @@ func (f *File) WriteToBuffer() (*bytes.Buffer, error) {
 	}
 
 	for path, content := range f.XLSX {
+		if _, ok := f.streams[path]; ok {
+			continue
+		}
 		fi, err := zw.Create(path)
 		if err != nil {
 			zw.Close()