Golang Gin Practice Serial 14 implementing export, Import Excel
Original address: Gin practice serial 14 implementing export, Import Excel
Project Address: Https://github.com/EDDYCJY/go ...
If it helps, you're welcome to a Star.
Objective
In this section, we will implement the export of label information, import function, which is a standard feature, I hope you master the basic use of the way
In addition, in this article we used 2 Excel packages, excelize the original XML format file structure, is through the TEALEG/XLSX format file structure evolved, so specifically here to show that you can according to their own scenes and love to use
Configuration
First, specify the storage path for the exported Excel file, and add the configuration in App.ini:
[app]...ExportSavePath = export/
To modify the Setting.go App struct:
type App struct { JwtSecret string PageSize int PrefixUrl string RuntimeRootPath string ImageSavePath string ImageMaxSize int ImageAllowExts []string ExportSavePath string LogSavePath string LogSaveName string LogFileExt string TimeFormat string}
In this case, you need to add the Exportsavepath configuration item, and change the previous imageprefixurl to Prefixurl to support both HOST acquisition
(Note the Getimagefullurl method for modifying Image.go)
Pkg
Create a new Pkg/export/excel.go file as follows:
package exportimport "github.com/EDDYCJY/go-gin-example/pkg/setting"func GetExcelFullUrl(name string) string { return setting.AppSetting.PrefixUrl + "/" + GetExcelPath() + name}func GetExcelPath() string { return setting.AppSetting.ExportSavePath}func GetExcelFullPath() string { return setting.AppSetting.RuntimeRootPath + GetExcelPath()}
Here write some commonly used methods, after the value of the way if there is a change, directly change the internal code can be invisible to the outside
Try the standard library
f, err := os.Create(export.GetExcelFullPath() + "test.csv")if err != nil { panic(err)}defer f.Close()f.WriteString("\xEF\xBB\xBF")w := csv.NewWriter(f)data := [][]string{ {"1", "test1", "test1-1"}, {"2", "test2", "test2-1"}, {"3", "test3", "test3-1"},}w.WriteAll(data)
In the standard library encoding/csv that Go provides, the natural support for reading and processing CSV files, in this section of the code, do the following:
1, OS. Create:
A test.csv file was created
2, F.writestring ("XEFXBBXBF"):
\xEF\xBB\xBF
is the UTF-8 BOM 16 format, where the use is to identify the encoding format of the file, usually appears at the beginning of the file, so the first step is to write it. If the encoding format of the UTF-8 is not identified, the written Chinese characters will be displayed as garbled
3, CSV. Newwriter:
func NewWriter(w io.Writer) *Writer { return &Writer{ Comma: ',', w: bufio.NewWriter(w), }}
4, W.writeall:
func (w *Writer) WriteAll(records [][]string) error { for _, record := range records { err := w.Write(record) if err != nil { return err } } return w.w.Flush()}
Writeall is actually a Write wrapper that needs attention at the end of the call w.w.Flush()
, which fully illustrates the Writeall usage scenario, and you can think about the author's design intent
Export
Service method
Open the Service/tag.go and add the Export method as follows:
Func (t *tag) Export (string, error) {tags, err: = T.getall () if err! = Nil {return "", err} file : = xlsx. NewFile () sheet, err: = file. Addsheet ("tag information") If err! = Nil {return "", err} titles: = []string{"ID", "name", "creator", "Creation Time", "Modified person", "modify Time "} row: = Sheet. AddRow () var cell *xlsx. Cell for _, Title: = Range Titles {cell = row. Addcell () cell. Value = title} for _, V: = Range Tags {values: = []string{StrConv. Itoa (v.id), V.name, V.createdby, StrConv. Itoa (V.createdon), V.modifiedby, StrConv. Itoa (V.modifiedon),} row = sheet. AddRow () for _, Value: = Range values {cell = row. Addcell () cell. Value = value}} time: = StrConv. Itoa (int (time). Now (). Unix ())) FileName: = "tags-" + Time + ". xlsx" FullPath: = Export. Getexcelfullpath () + filename err = file. Save (FullPath) if err! = Nil { Return "", err} return filename, nil}
Routers entrance
To open Routers/api/v1/tag.go, add the following method:
func ExportTag(c *gin.Context) { appG := app.Gin{C: c} name := c.PostForm("name") state := -1 if arg := c.PostForm("state"); arg != "" { state = com.StrTo(arg).MustInt() } tagService := tag_service.Tag{ Name: name, State: state, } filename, err := tagService.Export() if err != nil { appG.Response(http.StatusOK, e.ERROR_EXPORT_TAG_FAIL, nil) return } appG.Response(http.StatusOK, e.SUCCESS, map[string]string{ "export_url": export.GetExcelFullUrl(filename), "export_save_url": export.GetExcelPath() + filename, })}
Routing
Add the routing method to the Routers/router.go file as follows
apiv1 := r.Group("/api/v1")apiv1.Use(jwt.JWT()){ ... //导出标签 r.POST("/tags/export", v1.ExportTag)}
Validating interfaces
Access http://127.0.0.1:8000/tags/export
, the results are as follows:
{ "code": 200, "data": { "export_save_url": "export/tags-1528903393.xlsx", "export_url": "http://127.0.0.1:8000/export/tags-1528903393.xlsx" }, "msg": "ok"}
Finally, the address and save address of the exported file are returned through the interface.
Staticfs
Then you think, now direct access to the address must be unable to download the file, then how to do it?
Open the Router.go file and add the following code:
r.StaticFS("/export", http.Dir(export.GetExcelFullPath()))
If you do not understand, it is strongly recommended to review the previous chapters, extrapolate
Verifying downloads
Again visit the above Export_url, such as: http://127.0.0.1:8000/export/tags-1528903393.xlsx
, is not successful?
Import
Service method
Open the Service/tag.go and add the Import method as follows:
func (t *Tag) Import(r io.Reader) error { xlsx, err := excelize.OpenReader(r) if err != nil { return err } rows := xlsx.GetRows("标签信息") for irow, row := range rows { if irow > 0 { var data []string for _, cell := range row { data = append(data, cell) } models.AddTag(data[1], 1, data[2]) } } return nil}
Routers entrance
To open Routers/api/v1/tag.go, add the following method:
func ImportTag(c *gin.Context) { appG := app.Gin{C: c} file, _, err := c.Request.FormFile("file") if err != nil { logging.Warn(err) appG.Response(http.StatusOK, e.ERROR, nil) return } tagService := tag_service.Tag{} err = tagService.Import(file) if err != nil { logging.Warn(err) appG.Response(http.StatusOK, e.ERROR_IMPORT_TAG_FAIL, nil) return } appG.Response(http.StatusOK, e.SUCCESS, nil)}
Routing
Add the routing method to the Routers/router.go file as follows
apiv1 := r.Group("/api/v1")apiv1.Use(jwt.JWT()){ ... //导入标签 r.POST("/tags/import", v1.ImportTag)}
Verify
Here we will use the previously exported Excel file as the input, Access http://127.0.0.01:8000/tags/import
, check the return and the data is correctly inbound
Summarize
In this article, we briefly describe how Excel imports and exports are used, using the following 2 packages:
- Tealeg/xlsx
- 360entsecgroup-skylar/excelize
You can read how it is implemented and how it is used, which is more helpful for your control.
Extracurricular
- Tag: Export using Excelize to implement (perhaps you will find it easier OH)
- Tag: Import de-weight feature implementation
- Artice: Import, export function implementation
Also without losing the opportunity for your good practiced hand, if you are interested, you can try
Reference
Sample code for this series