Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I added argument -s Sheetname #9

Open
kshji opened this issue Oct 13, 2019 · 2 comments
Open

I added argument -s Sheetname #9

kshji opened this issue Oct 13, 2019 · 2 comments

Comments

@kshji
Copy link

kshji commented Oct 13, 2019

Sometimes it's easiert to make order to convert using Sheetname. Added param sheetName. Added open sheet using SheetName if not empty string.

package main

import (
        "errors"
        "flag"
        "fmt"
        "os"
        "strings"

        "github.com/tealeg/xlsx"
)

var xlsxPath = flag.String("f", "", "Path to an XLSX file")
var sheetIndex = flag.Int("i", 0, "Index of sheet to convert, zero based")
var sheetName = flag.String("s", "", "Name of sheet to convert")
var delimiter = flag.String("d", ";", "Delimiter to use between fields")

type outputer func(s string)

func generateCSVFromXLSXFile(excelFileName string, sheetIndex int, sheetName string, outputf outputer) error {                                              xlFile, error := xlsx.OpenFile(excelFileName)
        if error != nil {
                return error
        }
        sheetLen := len(xlFile.Sheets)
        switch {
        case sheetLen == 0:
                return errors.New("This XLSX file contains no sheets.")
        case sheetIndex >= sheetLen:
                return fmt.Errorf("No sheet %d available, please select a sheet between 0 and %d\n", sheetIndex, sheetLen-1)
        }
        sheet := xlFile.Sheets[sheetIndex]
        // or like to use sheet name ?
        if sheetName != ""  {
                sheet2, ok := xlFile.Sheet[sheetName]                                                                                                              
                if ok != true {                                                                                                                                             
                      return errors.New("This XLSX file contains not named sheet.")                                                                               
                }
                sheet=sheet2
        }
        for _, row := range sheet.Rows {
                var vals []string
                if row != nil {
                        for _, cell := range row.Cells {
                                str, err := cell.FormattedValue()
                                if err != nil {
                                        vals = append(vals, err.Error())
                                }
                                vals = append(vals, fmt.Sprintf("%q", str))
                        }
                        outputf(strings.Join(vals, *delimiter) + "\n")
                }
        }
        return nil
}

func main() {
        flag.Parse()
        if len(os.Args) < 3 {
                flag.PrintDefaults()
                return
        }
        flag.Parse()
        printer := func(s string) { fmt.Printf("%s", s) }
        if err := generateCSVFromXLSXFile(*xlsxPath, *sheetIndex, *sheetName, printer); err != nil {
                fmt.Println(err)
        }
}
@tealeg
Copy link
Owner

tealeg commented Oct 17, 2019

Hi @kshji - if you submit this as a pull request I'd be very happy to review and merge it to the codebase.

I don't know your background, but if you need help with the Pull Request process let me know.

@kshji
Copy link
Author

kshji commented Nov 3, 2019

I have updated only my own github using git. Not yet pull for others. So short howto list of git commands to pull my version main.go could be helpful.

Current version using csv writer and output is not so nice, because input already include quote chars around strings, csv.writer is not the best answer. Before csv.writer need to remove 1st and last " and then give string to the csv.writer would be nicer result. main_test.go fails with current version.

Also parameter listed with comma in function call is not so nice to add new parameters, need always update function call. Maybe using some structured flag would be more stable version for function call.

package main

import (
    "flag"
    "fmt"
)

type MyConfig struct {
        xlsxPath string
        sheetIndex int
        sheetName string
        delimiter string
}

func main() {
        myParam := new(MyConfig)
        flag.StringVar(&myParam.xlsxPath,"f", "", "Path to an XLSX file")
        flag.IntVar(&myParam.sheetIndex,"i", 0, "Index of sheet to convert, zero based")
        flag.StringVar(&myParam.sheetName,"s", "", "Name of sheet to convert")
        flag.StringVar(&myParam.delimiter,"d", ";", "Delimiter to use between fields")
        flag.Parse()
        someFunction(*myParam)  // using struct
}

func someFunction(Param MyConfig) {
    fmt.Println(Param)
    fmt.Println("xlsxPath",Param.xlsxPath)
    fmt.Println("sheetIndex",Param.sheetIndex)
    fmt.Println("sheetName",Param.sheetName)
    fmt.Println("delimiter",Param.delimiter)
}

Using Sheetname need only add
after line
sheet := xlFile.Sheets[sheetIndex]
lines:

        // or like to use sheet name ?
        if sheetName != ""  {
                sheet2, ok := xlFile.Sheet[sheetName]                                                                                                              
                if ok != true {                                                                                                                                             
                      return errors.New("This XLSX file contains not named sheet.")                                                                               
                }
                sheet=sheet2
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants