mirror of
https://github.com/unidoc/unioffice.git
synced 2025-04-25 13:48:53 +08:00
293 lines
7.5 KiB
Go
293 lines
7.5 KiB
Go
// Copyright 2017 Baliance. All rights reserved.
|
|
//
|
|
// Use of this source code is governed by the terms of the Affero GNU General
|
|
// Public License version 3.0 as published by the Free Software Foundation and
|
|
// appearing in the file LICENSE included in the packaging of this file. A
|
|
// commercial license can be purchased by contacting sales@baliance.com.
|
|
package spreadsheet_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/xml"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"testing"
|
|
|
|
"baliance.com/gooxml/schema/soo/sml"
|
|
|
|
"baliance.com/gooxml/spreadsheet"
|
|
"baliance.com/gooxml/testhelper"
|
|
"baliance.com/gooxml/zippkg"
|
|
)
|
|
|
|
func TestSimpleWorkbook(t *testing.T) {
|
|
wb := spreadsheet.New()
|
|
defer wb.Close()
|
|
sheet := wb.AddSheet()
|
|
sheet.Cell("A1").SetString("Hello World!")
|
|
|
|
got := bytes.Buffer{}
|
|
if err := wb.Validate(); err != nil {
|
|
t.Errorf("created an invalid sheet: %s", err)
|
|
}
|
|
wb.Save(&got)
|
|
testhelper.CompareGoldenZip(t, "simple-2.xlsx", got.Bytes())
|
|
}
|
|
|
|
func TestConstructor(t *testing.T) {
|
|
wb := spreadsheet.New()
|
|
defer wb.Close()
|
|
if wb == nil {
|
|
t.Errorf("expected a non-nil workbook")
|
|
}
|
|
if wb.X() == nil {
|
|
t.Errorf("expected a non-nil workbook XML entity")
|
|
}
|
|
if wb.ContentTypes.X() == nil {
|
|
t.Errorf("expected a non-nil content-types")
|
|
}
|
|
if wb.CoreProperties.X() == nil {
|
|
t.Errorf("expected a non-nil core properties")
|
|
}
|
|
if wb.AppProperties.X() == nil {
|
|
t.Errorf("expected a non-nil app properties")
|
|
}
|
|
if wb.Rels.X() == nil {
|
|
t.Errorf("expected a non-nil relationship")
|
|
}
|
|
if wb.StyleSheet.X() == nil {
|
|
t.Errorf("expected a non-nil stylesheet")
|
|
}
|
|
}
|
|
func TestWorkbookUnmarshal(t *testing.T) {
|
|
f, err := os.Open("testdata/workbook.xml")
|
|
if err != nil {
|
|
t.Fatalf("error reading content types file")
|
|
}
|
|
dec := xml.NewDecoder(f)
|
|
r := sml.NewWorkbook()
|
|
if err := dec.Decode(r); err != nil {
|
|
t.Errorf("error decoding content types: %s", err)
|
|
}
|
|
got := &bytes.Buffer{}
|
|
fmt.Fprintf(got, zippkg.XMLHeader)
|
|
enc := xml.NewEncoder(zippkg.SelfClosingWriter{W: got})
|
|
if err := enc.Encode(r); err != nil {
|
|
t.Errorf("error encoding content types: %s", err)
|
|
}
|
|
|
|
testhelper.CompareGoldenXML(t, "workbook.xml", got.Bytes())
|
|
}
|
|
|
|
func TestSimpleSheet(t *testing.T) {
|
|
wb := spreadsheet.New()
|
|
defer wb.Close()
|
|
sheet := wb.AddSheet()
|
|
row := sheet.AddRow()
|
|
cell := row.AddCell()
|
|
cell.SetString("testing 123")
|
|
got := bytes.Buffer{}
|
|
if err := wb.Validate(); err != nil {
|
|
t.Errorf("created an invalid spreadsheet: %s", err)
|
|
}
|
|
wb.Save(&got)
|
|
testhelper.CompareGoldenZip(t, "simple-1.xlsx", got.Bytes())
|
|
}
|
|
func TestOpen(t *testing.T) {
|
|
wb, err := spreadsheet.Open("testdata/simple-1.xlsx")
|
|
if err != nil {
|
|
t.Errorf("error opening workbook: %s", err)
|
|
}
|
|
defer wb.Close()
|
|
|
|
got := bytes.Buffer{}
|
|
if err := wb.Validate(); err != nil {
|
|
t.Errorf("created an invalid spreadsheet: %s", err)
|
|
}
|
|
wb.Save(&got)
|
|
testhelper.CompareZip(t, "simple-1.xlsx", got.Bytes(), true)
|
|
}
|
|
|
|
func TestOpenExcel2016(t *testing.T) {
|
|
wb, err := spreadsheet.Open("../testdata/Office2016/Excel-Windows.xlsx")
|
|
if err != nil {
|
|
t.Fatalf("error opening workbook: %s", err)
|
|
}
|
|
defer wb.Close()
|
|
|
|
got := bytes.Buffer{}
|
|
if err := wb.Validate(); err != nil {
|
|
t.Errorf("created an invalid spreadsheet: %s", err)
|
|
}
|
|
wb.Save(&got)
|
|
//testhelper.CompareZip(t, "../../testdata/Office2016/Excel-Windows.xlsx", got.Bytes())
|
|
}
|
|
|
|
func TestSheetCount(t *testing.T) {
|
|
wb := spreadsheet.New()
|
|
if err := wb.Validate(); err != nil {
|
|
t.Errorf("created an invalid spreadsheet: %s", err)
|
|
}
|
|
defer wb.Close()
|
|
if wb.SheetCount() != 0 {
|
|
t.Errorf("expected 0 sheets, got %d", wb.SheetCount())
|
|
}
|
|
wb.AddSheet()
|
|
if err := wb.Validate(); err != nil {
|
|
t.Errorf("created an invalid spreadsheet: %s", err)
|
|
}
|
|
if wb.SheetCount() != 1 {
|
|
t.Errorf("expected 1 sheets, got %d", wb.SheetCount())
|
|
}
|
|
wb.AddSheet()
|
|
if err := wb.Validate(); err != nil {
|
|
t.Errorf("created an invalid spreadsheet: %s", err)
|
|
}
|
|
if wb.SheetCount() != 2 {
|
|
t.Errorf("expected 2 sheets, got %d", wb.SheetCount())
|
|
}
|
|
}
|
|
|
|
func TestPreserveSpace(t *testing.T) {
|
|
ss := spreadsheet.New()
|
|
sheet := ss.AddSheet()
|
|
row := sheet.AddRow()
|
|
values := []string{" foo ", " bar \t", "foo\r\nbar", "\t\r\nfoo\t123\r\n"}
|
|
for i, s := range values {
|
|
cell := row.AddCell()
|
|
if i%2 == 0 {
|
|
cell.SetInlineString(s)
|
|
} else {
|
|
cell.SetString(s)
|
|
}
|
|
|
|
}
|
|
|
|
buf := bytes.Buffer{}
|
|
if err := ss.Save(&buf); err != nil {
|
|
log.Fatalf("error saving spreadsheet: %s", err)
|
|
}
|
|
|
|
op, err := spreadsheet.Read(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
|
|
if err != nil {
|
|
log.Fatalf("error loading saved spreadsheet: %s", err)
|
|
}
|
|
sheets := op.Sheets()
|
|
if len(sheets) != 1 {
|
|
t.Errorf("expected 1 sheet, got %d", len(sheets))
|
|
}
|
|
rows := sheets[0].Rows()
|
|
if len(rows) != 1 {
|
|
t.Errorf("expected 1 row, got %d", len(rows))
|
|
}
|
|
cells := rows[0].Cells()
|
|
if len(cells) != 4 {
|
|
t.Errorf("expected 4 cells, got %d", len(cells))
|
|
}
|
|
for i, c := range cells {
|
|
got, err := c.GetRawValue()
|
|
if err != nil {
|
|
t.Errorf("error retrieving cell value: %s", err)
|
|
}
|
|
if got != values[i] {
|
|
t.Errorf("expected cell value = %q, got %q", values[i], got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAddDefinedName(t *testing.T) {
|
|
wb := spreadsheet.New()
|
|
defer wb.Close()
|
|
if len(wb.DefinedNames()) != 0 {
|
|
t.Errorf("expeced no defined names on new wb")
|
|
}
|
|
name := "foo"
|
|
ref := "bar"
|
|
dn := wb.AddDefinedName(name, ref)
|
|
if len(wb.DefinedNames()) != 1 {
|
|
t.Errorf("expected 1 defined names on wb")
|
|
}
|
|
if dn.Name() != name {
|
|
t.Errorf("expected name = %s, got %s", name, dn.Name())
|
|
}
|
|
if dn.Content() != ref {
|
|
t.Errorf("expected content = %s, got %s", ref, dn.Content())
|
|
}
|
|
}
|
|
|
|
func ExampleWorkbook_AddDefinedName() {
|
|
wb := spreadsheet.New()
|
|
defer wb.Close()
|
|
sheet := wb.AddSheet()
|
|
productNames := wb.AddDefinedName("ProductNames", sheet.RangeReference("A2:A6"))
|
|
// now 'ProductNames' can be used in formulas, charts, etc.
|
|
fmt.Printf("%s refers to %s", productNames.Name(), productNames.Content())
|
|
// Output: ProductNames refers to 'Sheet 1'!$A$2:$A$6
|
|
}
|
|
|
|
func TestOpenComments(t *testing.T) {
|
|
wb, err := spreadsheet.Open("./testdata/comments.xlsx")
|
|
defer wb.Close()
|
|
if err != nil {
|
|
t.Fatalf("error opening workbook: %s", err)
|
|
}
|
|
|
|
sheet := wb.Sheets()[0]
|
|
if len(sheet.Comments().Comments()) != 1 {
|
|
t.Fatalf("sheet should have returned 1 existing comments")
|
|
}
|
|
cmt := sheet.Comments().Comments()[0]
|
|
if cmt.Author() != "John Doe" {
|
|
t.Errorf("error reading comment author")
|
|
}
|
|
}
|
|
func TestWorkbookProtection(t *testing.T) {
|
|
wb := spreadsheet.New()
|
|
defer wb.Close()
|
|
if wb.X().WorkbookProtection != nil {
|
|
t.Errorf("expected no protection for new workbook")
|
|
}
|
|
wb.Protection()
|
|
if wb.X().WorkbookProtection == nil {
|
|
t.Errorf("expected protection")
|
|
}
|
|
wb.ClearProtection()
|
|
if wb.X().WorkbookProtection != nil {
|
|
t.Errorf("expected no protection after clear")
|
|
}
|
|
}
|
|
|
|
func TestSheetGetName(t *testing.T) {
|
|
wb := spreadsheet.New()
|
|
defer wb.Close()
|
|
s := wb.AddSheet()
|
|
if _, err := wb.GetSheet("foo"); err == nil {
|
|
t.Errorf("expected an error")
|
|
}
|
|
if _, err := wb.GetSheet(s.Name()); err != nil {
|
|
t.Errorf("expected no error")
|
|
}
|
|
}
|
|
|
|
// TestOpenOrderedSheets test for issue #154 where sheet title didn't match sheet content.
|
|
func TestOpenOrderedSheets(t *testing.T) {
|
|
wb, err := spreadsheet.Open("./testdata/ordered-sheets.xlsx")
|
|
defer wb.Close()
|
|
if err != nil {
|
|
t.Fatalf("error opening workbook: %s", err)
|
|
}
|
|
|
|
for i, sheet := range wb.Sheets() {
|
|
expContent := fmt.Sprintf("%d", i+1)
|
|
if sheet.Name() != expContent {
|
|
t.Errorf("expected sheet %d name = %s, got %s", i, expContent, sheet.Name())
|
|
}
|
|
got := sheet.Cell("A1").GetFormattedValue()
|
|
if got != expContent {
|
|
t.Errorf("expected sheet %d cell A1 = %s, got %s", i, expContent, got)
|
|
}
|
|
}
|
|
|
|
}
|