I want to overwrite some data on a designed excel already with golang.
So I found a module named excelize.
I tried to read and write seeing the document as below.
func main()
f, err := excelize.OpenFile("ab.xlsx")
if err != nil {
fmt.Println(err)
return
}
rows, err := f.GetRows("Sheet1")
for _, row := range rows {
for _, colCell := range row {
fmt.Print(colCell, "\t")
}
fmt.Println()
}
}
I can read data or write excel.
But my goal is I just want to read an excel with cell designed and overwrite just data on it.
How can I make this? Can you give me some advice?
Thank you for reading it.
f, err := excelize.OpenFile("ab.xlsx")
if err != nil {
fmt.Println(err)
return
}
if err := f.SaveAs("Book2.xlsx"); err != nil {
fmt.Println(err)
}
I found the solution. Thank you.
Related
I have a requirement, it needs to import xlsx file to bulk insert objects into database.
Now, I am able to insert via pseudocode like below
import (
"github.com/xuri/excelize/v2"
)
file, _, err := c.Request.FormFile("file")
if err != nil {
return
}
xlsx, err := excelize.OpenReader(f)
if err != nil {
return err
}
defer func() {
if err := xlsx.Close(); err != nil {
log.L(c).Info(err.Error())
}
}()
rows, err := xlsx.GetRows(xlsx.GetSheetName(xlsx.GetActiveSheetIndex()))
if err != nil {
fmt.Println(err)
return nil, err
}
type TestObj struct{
Test0 string gorm:"column:test0" // Required fields
Test1 string gorm:"column:test1" // Required fields
Test2 string gorm:"column:test2" // Optional
Test3 string gorm:"column:test3" // Optional
Test4 string gorm:"column:test4" // Optional
}
objs := []TestObj{}
for i, row := range rows {
if i == 0{ //
continue
}
var data TestObj
for k, colCell := range row {
if k==0{
data.Test0=colCell
}
if k==1{
data.Test1=colCell
}
if k==2{
data.Test2=colCell
}
if k==3{
data.Test3=colCell
}
if k==4{
data.Test4=colCell
}
}
objs= append(objs, data)
}
service.BatchInsert(c,objs)
The way of the above code limits the flexibility of inserting data, for example, there are three options for Test2, Test3, and Test4.
Some uploaded forms may only contain some optional attributes. For example, the excel file contains Test1, Test0, Test4, and Test3, an error occurs when reading.
Is there some way to code that supports multiple upload file formats, such as Test0、Test1,Test4,Test3, and Test1,Test0,Test2, etc.
I really appreciate any help with this.
I'm trying to monitor a file using the fsnotify packet in golang.
I saw few examples like this and I would like to know if this is the best way of using fsnotify:
package main
import (
"log"
"github.com/howeyc/fsnotify"
)
func main() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
done := make(chan bool)
// Process events
go func() {
for {
select {
case ev := <-watcher.Event:
log.Println("event:", ev)
case err := <-watcher.Error:
log.Println("error:", err)
}
}
}()
err = watcher.Watch("testDir")
if err != nil {
log.Fatal(err)
}
<-done
var get_info := []string
get_info = read_file(path_to_file)
watcher.Close()
}
Basically I'm passing a path where the file is located and geting the resul in a string variable.
Everytime I change the file I would like to read the file and get the result.
I'm not sure if I'm using fsnotify correctly base on that example. Also, I'm not sure where to put the file path in the fsnotify to monitor that file.
You're leveraging fsnotify pretty much correctly, the only change would likely be that you want to utilize the channel to grab events and then use the event to extract the file name that changed. This would allow you to monitor multiple files and also in your example I don't believe you ever pass a value into done for it to properly finish waiting on the channel and read the file contents.
I'm adding a simple sample below that gets rid of the go routine and simply listens for changes on the main thread.
func main() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
panic(err)
}
err = watcher.Add("file.txt")
if err != nil {
panic(err)
}
for {
select {
case ev := <-watcher.Events:
log.Println("event:", ev)
if ev.Op&fsnotify.Write == fsnotify.Write {
contents, err := ioutil.ReadFile(ev.Name)
if err != nil {
// handle error
}
log.Println("modified file:", string(contents))
}
case err := <-watcher.Errors:
log.Println("error:", err)
}
}
}
I am trying to follow the tutorial here : https://goethereumbook.org/block-query/
In his code , he calls the header and then hard codes it into blockNumber.
header, err := client.HeaderByNumber(context.Background(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(header.Number.String()) // 5671744
blockNumber := big.NewInt(5671744)
I have attempted to improve on this and converted the string to int64.
header, err := client.HeaderByNumber(context.Background(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(header.Number.String())
var stringBlockNumber = header.Number.String()
int64BlockNumber, err := strconv.ParseInt(stringBlockNumber, 10, 64)
if err != nil {
log.Fatal(err)
}
blockNumber := big.NewInt(int64BlockNumber)
block, err := client.BlockByNumber(context.Background(), blockNumber)
if err != nil {
log.Fatal(err)
}
This works until in try to add the following line:
fmt.Println(block.Number.Uint64())
I get the following error in the terminal :
./queryBlock.go:41:26: block.Number.Uint64 undefined (type func()
*big.Int has no field or method Uint64)
I would appreciate any pointers on this.
After getting the block by number through client.BlockByNumber, block is of type Block from /github.com/ethereum/go-ethereum/core/types.
Number of Block is a method, which returns a *big.Int instead of being a field of that type. So To retrieve the number, you should call the method, i.e, block.Number().
Trying to print a list of routes from within a network namespace. The netlink.RouteList function requires an Interface type. A list of all interfaces is gathered by LinkList().
I'm trying to call RouteList with every interface and print it's output. RouteList returns type Route where I'm trying to print the int LinkIndex.
It appears as if my loop
for j := range rt {
log.Printf("Route: %d : %d",rt[j].LinkIndex)
}
Isn't executing for some reason, running another Printf test in there yields nothing.
Why wouldn't this loop be called?
func (h *NSHandle) showInts() {
nh := (*netlink.Handle)(h) //cast required
int, err := nh.LinkList()
if err != nil {
log.Fatal(err)
}
log.Printf("Namespace Ints:")
for i, r := range int {
log.Printf("%d: %s", i, r.Attrs().Name)
rt, err := netlink.RouteList(r,-1)
if err != nil {
log.Fatal(err)
}
for j := range rt {
log.Printf("Route: %d : %d",rt[j].LinkIndex)
}
}
}
This was a bad question. Soon after posting I had realised that the array was obviously empty due to the fact that RouteList was being called without the receiver Handler. This was fixed by simply:
for i, r := range rl {
log.Printf("%d: %s", i, LinkIndex)
}
I need to use password authenticated scp to download a file from a server. How do I do so using Go? Tried the following code, but it doesn't pass in the password.
package main
import (
"os/exec"
"time"
)
func main() {
password := "password"
cmd := exec.Command("scp", "admin#192.168.1.150:file", "file")
in, err := cmd.StdinPipe()
if err != nil {
panic(err)
}
defer in.Close()
out, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}
defer out.Close()
if err = cmd.Run(); err != nil {
panic(err)
}
go func() {
time.Sleep(10 * time.Second)
_, err = in.Write([]byte(password + "\n"))
if err != nil {
panic(err)
}
}()
}
Edit: I ended up using the gexpect (github.com/ThomasRooney/gexpect) library.
package main
import (
"github.com/ThomasRooney/gexpect"
"log"
)
func main() {
child, err := gexpect.Spawn("scp admin#192.168.1.150:file file")
if err != nil {
log.Fatalln(err)
}
child.Expect("password:")
child.SendLine("password")
child.Interact()
child.Close()
}
The answer to this self-answered question might help:
Golang write input and get output from terminal process
at least, he mentions in the answer that he "was able to get ssh access working with a password", which is not mentioned explicitly in the question - that's why you probably didn't find it while searching the site?