golang读取excel文件(个人经验)
v1,v2版本访问地址
**注:本篇使用的工具包为下列v2版本
github.com/xuri/excelize/v2
之前的 工具包为下列v1版本**
github.com/360EntSecGroup-Skylar/excelize~~
其中
v2与v1的区别
日期
v2:默认为日期格式的字符串
v1:以到excel日期的浮点数(如果要使用需要转换,转换方法参考v2版本里面date文件中的timeFromExcelTime 方法)
我的公共工具方法
导入方法一,读取本地Excel文件(文件类型为.xlsx格式)
(根据表格名称获取指定表格数据)(返回的二维数据均为字符串格式,错误情况)
//filename:指定文件路径名称,例如:"D:/aa.xlsx"
//tablename: (可变参数)指定Excel中的某个表格名,不传默认第一个表格
func ReadExcel(filename string, tablename ... string) ([][]string,error) {
f, err := excelize.OpenFile(filename) //
if err != nil {
return nil,err
}
firstSheet := ""
if len(tableau) > 0 {
firstSheet = tableau[0]
} else {
firstSheet = f.GetSheetName(0)
}
rows, err := f.GetRows(firstSheet)
return rows,err
//以下为遍历数据(我个人禁用掉了)
/*for _, row := range rows {
for _, colCell := range row {
fmt.Print(colCell, "\t")
}
fmt.Println()
}*/
}
导入方法二 读取Excel文件流(文件类型为.xlsx格式)
//直接传入整个文件
type File interface {
io.Reader
io.ReaderAt
io.Seeker
io.Closer
}
func ReadExcelFile(file File,tableName ... string) ([][]string,error) {
f, err := excelize.OpenReader(file)
if err != nil {
return nil,err
}
//默认读取第一个
firstSheet := ""
if len(tableName) > 0 {
firstSheet = tableName[0]
} else {
firstSheet = f.GetSheetName(0)
}
rows, err := f.GetRows(firstSheet)
return rows,err
}
导出方法一 ,限制工作簿每页条数,避免数据过多导致导出出现问题
func WriteExcel(filename string, value [][]string, tableName ...string) error {
f := excelize.NewFile()
//默认Excel每个页面保存500条数据,超出500条就新建一个页面保存,page为每页最多保存条数
page := 500
//默认保存开始名称
firstSheet := "Sheet"
if len(tableName) > 0 {
firstSheet = tableName[0]
}
// Create a new sheet.
sheetRow := int(math.Floor(float64(len(value)/page)) + 1)
for j := 0; j < sheetRow; j++ {
index := f.NewSheet(firstSheet + gconv.String(j+1))
if j > 0 {
for k, v := range value[0] { //列
path, err := excelize.ColumnNumberToName(k + 1)
if err != nil {
return err
}
err = f.SetCellValue(firstSheet+gconv.String(j+1), path+gconv.String(1), v)
if err != nil {
return err
}
}
for i := 0 + j*page; i < (j+1)*page; i++ { //行
if len(value) < i+1 {
break
}
for k, v := range value[i] { //列
path, err := excelize.ColumnNumberToName(k + 1)
if err != nil {
return err
}
err = f.SetCellValue(firstSheet+gconv.String(j+1), path+gconv.String(i+2-j*page), v)
if err != nil {
return err
}
}
}
} else {
for i := 0 + j*page; i < (j+1)*page; i++ { //行
if len(value) < i+1 {
break
}
for k, v := range value[i] { //列
path, err := excelize.ColumnNumberToName(k + 1)
if err != nil {
return err
}
err = f.SetCellValue(firstSheet+gconv.String(j+1), path+gconv.String(i+1-j*page), v)
if err != nil {
return err
}
}
}
}
f.SetActiveSheet(index - 1)
}
if err := f.SaveAs(filename); err != nil {
return err
}
return nil
}
导入示例
controller中,我是使用的goframe框架
func import(r *ghttp.Request) {
//首先,获取form-data传过来的excel文件数据
file := r.GetUploadFile("file")
if file == nil {
fmt.Println("上传文件不能为空")
}
/*if file.Size > maxSize {
fmt.Println("上传文件不能超过1G")
}*/
//验证文件类型
filesuffix := path.Ext(file.Filename) // 文件类型
if filesuffix != ".xlsx" {
fmt.Println("文件类型错误")
}
open, err := file.Open()
if err != nil {
fmt.Println("打开文件失败")
}
//我个人使用的方法二,默认打开一个,所以不传表格名了
res, err := utils.ReadExcelFile(open)
if err != nil {
fmt.Println("打开文件第一个表格失败")
}
//已获取到excel的sheet1表的数据,然后传到service处理就行了(处理方法就不贴出来了)
if result, err := service.file.DealExcelSave(r.Context(), res); err != nil {
response.JsonExit(r, 400, err.Error())
} else {
response.JsonExitOK(r, result)
}
}
导出示例
func (s *Api) Export(r *ghttp.Request) {
//获取数据
var detailReq *Req
if err := r.Parse(&detailReq); err != nil {
response.JsonExit(r, 400, err.Error())
}
list, err := service.Data.Data(detailReq)
if err != nil {
response.JsonExit(r, 400, err.Error())
}
//创建临时目录,并在结束后删除
tempDir, err := ioutil.TempDir("", "excel-")
if err != nil {
response.JsonExit(r, 400, err.Error())
}
defer os.RemoveAll(tempDir)
file, err := ioutil.TempFile(tempDir, "excel-*.xlsx")
if err != nil {
response.JsonExit(r, 400, err.Error())
}
defer os.Remove(file.Name())
writer := r.Response.ResponseWriter
req := r.Request
path := file.Name() //放置在临时文件夹
err = service.Report.DealExport(path, list, detailReq)
if err != nil {
response.JsonExit(r, 400, err.Error())
}
//utils.WriteExcel(path,[][]string{{"A1","A2"},{"B1","B2"}})
http.ServeFile(writer, req, path)
}
func (s *reportService) DealBillchargeDetailReportExport(path string, data []Data, req *Req) error {
var result [][]string //二位数组,里面的一维数组按照excle排列
//中间过程胜率,按业务需求给result添加数据就行了
//最后,使用工具包,导出excle文件
err = utils.WriteExcel(path, result)
if err != nil {
return err
}
return nil
}