reader.go 2.2 KB
package exceltool

import (
	"io"

	excelize "github.com/360EntSecGroup-Skylar/excelize/v2"
)

// ExcelListReader 读取基础excel表格,
// 指定读取的列表区域的第一行作为表头字段处理,表头字段唯一
type ExcelListReader struct {
	RowStart int                                     //从第几行开始,零值做为起始
	RowEnd   func(index int, rowsData []string) bool //第几行结束,
	ColStart int                                     //第几列开始,零值做为起始
	ColEnd   int                                     //第几列结束,
	Sheet    string                                  //获取的表格
}

func NewExcelListReader() *ExcelListReader {
	rowEnd := func(index int, rowsData []string) bool {
		var allEmpty bool = true
		for _, v := range rowsData {
			if allEmpty && len(v) > 0 {
				allEmpty = false
				break
			}
		}
		return allEmpty
	}
	return &ExcelListReader{
		RowEnd: rowEnd,
	}
}

func (eRead ExcelListReader) OpenReader(r io.Reader) ([]map[string]string, error) {
	xlsxFile, err := excelize.OpenReader(r)
	if err != nil {
		return nil, err
	}
	rows, err := xlsxFile.Rows(eRead.Sheet)
	if err != nil {
		return nil, err
	}
	var (
		datas        = make([]map[string]string, 0) //数据列表
		listHead     = make(map[int]string)         //map[索引数字]列表头字符串
		rowIndex int = 0
	)
	for rows.Next() {
		cols, err := rows.Columns()
		if err != nil {
			return nil, err
		}
		if readEnd := eRead.RowEnd(rowIndex, cols); readEnd {
			break
		}
		if rowIndex < eRead.RowStart {
			rowIndex++
			continue
		}
		listRowData := make(map[string]string)
		for colK, colV := range cols {
			if eRead.ColEnd != 0 && colK > eRead.ColEnd {
				break
			}
			if colK < eRead.ColStart {
				continue
			}
			if rowIndex == eRead.RowStart {
				//指定的数据列表第一行作为列表头处理
				listHead[colK] = colV
			}
			if rowIndex > eRead.RowStart {
				//指定的数据列表第二行开始作为列表数据内容处理
				headK := listHead[colK]
				listRowData[headK] = colV
			}
		}
		if rowIndex > eRead.RowStart {
			//指定的数据列表第二行开始作为列表数据内容处理
			datas = append(datas, listRowData)
		}
		rowIndex++
	}
	return datas, nil
}