rows.go 3.6 KB
Newer Older
A
ahmad 已提交
1 2 3 4
package excelize

import (
	"encoding/xml"
5
	"strconv"
A
ahmad 已提交
6 7 8
	"strings"
)

9
// GetRows return all the rows in a sheet by given "sheet" + index, for example:
10
//
11 12
//    index := xlsx.GetSheetIndex("Sheet2")
//    rows := xlsx.GetRows("sheet" + strconv.Itoa(index))
13 14 15 16 17 18 19 20
//    for _, row := range rows {
//        for _, colCell := range row {
//            fmt.Print(colCell, "\t")
//        }
//        fmt.Println()
//    }
//
func (f *File) GetRows(sheet string) [][]string {
xurime's avatar
xurime 已提交
21
	xlsx := f.workSheetReader(sheet)
22
	rows := [][]string{}
23
	name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml"
xurime's avatar
xurime 已提交
24 25 26
	if xlsx != nil {
		output, _ := xml.Marshal(f.Sheet[name])
		f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpace(string(output)))
A
ahmad 已提交
27
	}
xurime's avatar
xurime 已提交
28 29
	decoder := xml.NewDecoder(strings.NewReader(f.readXML(name)))
	d, _ := readXMLSST(f)
30
	var inElement string
xurime's avatar
xurime 已提交
31
	var r xlsxRow
32
	var row []string
xurime's avatar
xurime 已提交
33 34 35 36 37 38 39 40 41
	tr, tc := f.getTotalRowsCols(sheet)
	for i := 0; i < tr; i++ {
		row = []string{}
		for j := 0; j <= tc; j++ {
			row = append(row, "")
		}
		rows = append(rows, row)
	}
	decoder = xml.NewDecoder(strings.NewReader(f.readXML(name)))
42 43 44 45 46 47 48 49 50
	for {
		token, _ := decoder.Token()
		if token == nil {
			break
		}
		switch startElement := token.(type) {
		case xml.StartElement:
			inElement = startElement.Name.Local
			if inElement == "row" {
xurime's avatar
xurime 已提交
51
				r = xlsxRow{}
52
				decoder.DecodeElement(&r, &startElement)
xurime's avatar
xurime 已提交
53
				cr := r.R - 1
54
				for _, colCell := range r.C {
xurime's avatar
xurime 已提交
55
					c := titleToNumber(strings.Map(letterOnlyMapF, colCell.R))
56
					val, _ := colCell.getValueFrom(f, d)
xurime's avatar
xurime 已提交
57
					rows[cr][c] = val
58 59 60
				}
			}
		default:
61 62
		}
	}
63
	return rows
A
ahmad 已提交
64 65
}

xurime's avatar
xurime 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
// getTotalRowsCols provides a function to get total columns and rows in a
// sheet.
func (f *File) getTotalRowsCols(sheet string) (int, int) {
	name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml"
	decoder := xml.NewDecoder(strings.NewReader(f.readXML(name)))
	var inElement string
	var r xlsxRow
	var tr, tc int
	for {
		token, _ := decoder.Token()
		if token == nil {
			break
		}
		switch startElement := token.(type) {
		case xml.StartElement:
			inElement = startElement.Name.Local
			if inElement == "row" {
				r = xlsxRow{}
				decoder.DecodeElement(&r, &startElement)
				tr = r.R
				for _, colCell := range r.C {
					col := titleToNumber(strings.Map(letterOnlyMapF, colCell.R))
					if col > tc {
						tc = col
					}
				}
			}
		default:
		}
	}
	return tr, tc
}

N
Nikolas Silva 已提交
99 100 101 102 103 104 105 106 107 108 109 110
// SetRowHeight provides a function to set the height of a single row.
// For example:
//
//    xlsx := excelize.CreateFile()
//    xlsx.SetRowHeight("Sheet1", 0, 50)
//    err := xlsx.Save()
//    if err != nil {
//        fmt.Println(err)
//        os.Exit(1)
//    }
//
func (f *File) SetRowHeight(sheet string, rowIndex int, height float64) {
xurime's avatar
xurime 已提交
111
	xlsx := f.workSheetReader(sheet)
N
Nikolas Silva 已提交
112 113
	rows := rowIndex + 1
	cells := 0
xurime's avatar
xurime 已提交
114
	completeRow(xlsx, rows, cells)
N
Nikolas Silva 已提交
115 116 117 118
	xlsx.SheetData.Row[rowIndex].Ht = strconv.FormatFloat(height, 'f', -1, 64)
	xlsx.SheetData.Row[rowIndex].CustomHeight = true
}

119
// readXMLSST read xmlSST simple function.
120
func readXMLSST(f *File) (*xlsxSST, error) {
A
ahmad 已提交
121
	shardStrings := xlsxSST{}
122
	err := xml.Unmarshal([]byte(f.readXML("xl/sharedStrings.xml")), &shardStrings)
123
	return &shardStrings, err
A
ahmad 已提交
124 125
}

126 127
// getValueFrom return a value from a column/row cell, this function is inteded
// to be used with for range on rows an argument with the xlsx opened file.
128
func (xlsx *xlsxC) getValueFrom(f *File, d *xlsxSST) (string, error) {
129 130 131 132
	switch xlsx.T {
	case "s":
		xlsxSI := 0
		xlsxSI, _ = strconv.Atoi(xlsx.V)
xurime's avatar
xurime 已提交
133 134 135 136 137 138 139
		if len(d.SI[xlsxSI].R) > 0 {
			value := ""
			for _, v := range d.SI[xlsxSI].R {
				value += v.T
			}
			return value, nil
		}
140 141 142 143 144 145
		return d.SI[xlsxSI].T, nil
	case "str":
		return xlsx.V, nil
	default:
		return xlsx.V, nil
	}
A
ahmad 已提交
146
}