package excelize import ( "archive/zip" "encoding/xml" "fmt" "strconv" "strings" ) // FileList define a populated xlsx.File struct. type FileList struct { Key string Value string } // OpenFile take the name of an XLSX file and returns a populated // xlsx.File struct for it. func OpenFile(filename string) (file []FileList, err error) { var f *zip.ReadCloser f, err = zip.OpenReader(filename) if err != nil { return nil, err } file, err = ReadZip(f) return } // SetCellInt provide function to set int type value of a cell func SetCellInt(file []FileList, sheet string, axis string, value int) []FileList { axis = strings.ToUpper(axis) var xlsx xlsxWorksheet col := getColIndex(axis) row := getRowIndex(axis) xAxis := row - 1 yAxis := titleToNumber(col) name := `xl/worksheets/` + strings.ToLower(sheet) + `.xml` xml.Unmarshal([]byte(readXML(file, name)), &xlsx) rows := xAxis + 1 cell := yAxis + 1 xlsx = checkRow(xlsx) xlsx = completeRow(xlsx, rows, cell) xlsx = completeCol(xlsx, rows, cell) xlsx.SheetData.Row[xAxis].C[yAxis].T = "" xlsx.SheetData.Row[xAxis].C[yAxis].V = strconv.Itoa(value) output, err := xml.MarshalIndent(xlsx, "", "") if err != nil { fmt.Println(err) } saveFileList(file, name, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output)))) return file } // SetCellStr provide function to set string type value of a cell func SetCellStr(file []FileList, sheet string, axis string, value string) []FileList { axis = strings.ToUpper(axis) var xlsx xlsxWorksheet col := getColIndex(axis) row := getRowIndex(axis) xAxis := row - 1 yAxis := titleToNumber(col) name := `xl/worksheets/` + strings.ToLower(sheet) + `.xml` xml.Unmarshal([]byte(readXML(file, name)), &xlsx) rows := xAxis + 1 cell := yAxis + 1 xlsx = checkRow(xlsx) xlsx = completeRow(xlsx, rows, cell) xlsx = completeCol(xlsx, rows, cell) xlsx.SheetData.Row[xAxis].C[yAxis].T = "str" xlsx.SheetData.Row[xAxis].C[yAxis].V = value output, err := xml.MarshalIndent(xlsx, "", "") if err != nil { fmt.Println(err) } saveFileList(file, name, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output)))) return file } // Completion column element tags of XML in a sheet func completeCol(xlsx xlsxWorksheet, row int, cell int) xlsxWorksheet { if len(xlsx.SheetData.Row) < cell { for i := len(xlsx.SheetData.Row); i < cell; i++ { xlsx.SheetData.Row = append(xlsx.SheetData.Row, xlsxRow{ R: i + 1, }) } } for k, v := range xlsx.SheetData.Row { if len(v.C) < cell { start := len(v.C) for iii := start; iii < cell; iii++ { xlsx.SheetData.Row[k].C = append(xlsx.SheetData.Row[k].C, xlsxC{ R: toAlphaString(iii+1) + strconv.Itoa(k+1), }) } } } return xlsx } // Completion row element tags of XML in a sheet func completeRow(xlsx xlsxWorksheet, row int, cell int) xlsxWorksheet { if len(xlsx.SheetData.Row) < row { for i := len(xlsx.SheetData.Row); i < row; i++ { xlsx.SheetData.Row = append(xlsx.SheetData.Row, xlsxRow{ R: i + 1, }) } for ii := 0; ii < row; ii++ { start := len(xlsx.SheetData.Row[ii].C) if start == 0 { for iii := start; iii < cell; iii++ { xlsx.SheetData.Row[ii].C = append(xlsx.SheetData.Row[ii].C, xlsxC{ R: toAlphaString(iii+1) + strconv.Itoa(ii+1), }) } } } } return xlsx } // Replace xl/worksheets/sheet%d.xml XML tags to self-closing for compatible Office Excel 2007 func replaceWorkSheetsRelationshipsNameSpace(workbookMarshal string) string { oldXmlns := `` newXmlns := `` workbookMarshal = strings.Replace(workbookMarshal, oldXmlns, newXmlns, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) workbookMarshal = strings.Replace(workbookMarshal, `>`, ` />`, -1) return workbookMarshal } // Check XML tags and fix discontinuous case, for example: // // // // // // // // // in this case, we should to change it to // // // // // // // // // // // func checkRow(xlsx xlsxWorksheet) xlsxWorksheet { for k, v := range xlsx.SheetData.Row { lenCol := len(v.C) if lenCol < 1 { continue } endR := getColIndex(v.C[lenCol-1].R) endRow := getRowIndex(v.C[lenCol-1].R) endCol := titleToNumber(endR) if lenCol < endCol { oldRow := xlsx.SheetData.Row[k].C xlsx.SheetData.Row[k].C = xlsx.SheetData.Row[k].C[:0] tmp := []xlsxC{} for i := 0; i <= endCol; i++ { fixAxis := toAlphaString(i+1) + strconv.Itoa(endRow) tmp = append(tmp, xlsxC{ R: fixAxis, }) } xlsx.SheetData.Row[k].C = tmp for _, y := range oldRow { colAxis := titleToNumber(getColIndex(y.R)) xlsx.SheetData.Row[k].C[colAxis] = y } } } return xlsx }