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 10 11 12 13 14 15 16 17 18 19
// GetRows return all the rows in a sheet, for example:
//
//    rows := xlsx.GetRows("Sheet2")
//    for _, row := range rows {
//        for _, colCell := range row {
//            fmt.Print(colCell, "\t")
//        }
//        fmt.Println()
//    }
//
func (f *File) GetRows(sheet string) [][]string {
20
	rows := [][]string{}
21
	name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml"
22 23
	decoder := xml.NewDecoder(strings.NewReader(f.readXML(name)))
	d, err := readXMLSST(f)
24
	if err != nil {
25
		return rows
A
ahmad 已提交
26
	}
27
	var inElement string
xurime's avatar
xurime 已提交
28
	var r xlsxRow
29
	var row []string
xurime's avatar
xurime 已提交
30 31 32 33 34 35 36 37 38
	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)))
39 40 41 42 43 44 45 46 47
	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 已提交
48
				r = xlsxRow{}
49
				decoder.DecodeElement(&r, &startElement)
xurime's avatar
xurime 已提交
50
				cr := r.R - 1
51
				for _, colCell := range r.C {
xurime's avatar
xurime 已提交
52
					c := titleToNumber(strings.Map(letterOnlyMapF, colCell.R))
53
					val, _ := colCell.getValueFrom(f, d)
xurime's avatar
xurime 已提交
54
					rows[cr][c] = val
55 56 57
				}
			}
		default:
58 59
		}
	}
60
	return rows
A
ahmad 已提交
61 62
}

xurime's avatar
xurime 已提交
63 64 65 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
// 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 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
// 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) {
	xlsx := xlsxWorksheet{}
	name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml"
	xml.Unmarshal([]byte(f.readXML(name)), &xlsx)

	rows := rowIndex + 1
	cells := 0

115
	completeRow(&xlsx, rows, cells)
N
Nikolas Silva 已提交
116 117 118 119 120 121 122 123

	xlsx.SheetData.Row[rowIndex].Ht = strconv.FormatFloat(height, 'f', -1, 64)
	xlsx.SheetData.Row[rowIndex].CustomHeight = true

	output, _ := xml.Marshal(xlsx)
	f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpace(string(output)))
}

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

131 132
// 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.
133
func (xlsx *xlsxC) getValueFrom(f *File, d *xlsxSST) (string, error) {
134 135 136 137
	switch xlsx.T {
	case "s":
		xlsxSI := 0
		xlsxSI, _ = strconv.Atoi(xlsx.V)
xurime's avatar
xurime 已提交
138 139 140 141 142 143 144
		if len(d.SI[xlsxSI].R) > 0 {
			value := ""
			for _, v := range d.SI[xlsxSI].R {
				value += v.T
			}
			return value, nil
		}
145 146 147 148 149 150
		return d.SI[xlsxSI].T, nil
	case "str":
		return xlsx.V, nil
	default:
		return xlsx.V, nil
	}
A
ahmad 已提交
151
}