Search code examples
gogoogle-cloud-storage360entsecgroup-skylar-excelize

Upload .xlsx file to google cloud storage


I have this API written in Go that creates an .xlsx file, using excelize, from fetched data from DB that I want to upload to private GCS bucket. But the problem is after I uploaded the file, it says that the file type is application/zip not application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.

type Connection struct {
    Credential    string
    BucketName    string
    APIKey        string
    ProjectID     string
    AccessToken   string
    BaseURL       string
    GcpCredential *google.Credentials
}

func (conn *Connection) Upload(url, name string) (err error) {
    ctx := context.Background()
    client, err := storage.NewClient(ctx, option.WithCredentialsFile(conn.Credential))
    if err != nil {
        return err
    }

    err = write(client, conn.BucketName, name, url)

    return err
}

func write(client *storage.Client, bucket, object, url string) error {
    ctx := context.Background()
    f, err := os.Open(url)
    if err != nil {
        return err
    }
    defer f.Close()

    wc := client.Bucket(bucket).Object(object).NewWriter(ctx)
    _, err = io.Copy(wc, f)
    if err != nil {
        return err
    }
    if err := wc.Close(); err != nil {
        return err
    }

    return nil
}

//In other file, generate excel file and upload it using above code
xlsx := excelize.NewFile()
//setup file content
...

//save to local machine located in uploadURL
err = xlsx.SaveAs(uploadURL)

//then upload to GCS bucket
err = h.Googlestorage.Upload(uploadURL, fileNameInGCS)
if err != nil {
    SendBadRequest(w, err.Error())
    return
}

//then generate signed URL for client to access the file

This is a problem because when I generate a signed URL of the file, it's downloaded as .zip file not .xlsx.

"{file path in bucket}.xlsx?Expires=1617698911&
GoogleAccessId={googleAccessID}&
Signature={someGeneratedSignature}"

How do I fix this? Is there a problem with the way I upload the file?


Solution

  • You can use the ObjectHandle.Update function

    
        _, err := client.Bucket(bucket).Object(object).Update(ctx, storage.ObjectAttrsToUpdate{
            ContentType:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        })