github.com/jonas-p/go-shp@v0.1.1
github.com/tealeg/xlsx
├─excel
├─html
├─shape
├─src
│ └─main
└─staticjavascript
func GetCols(shapefile string) []shp.Field {
shape, err := shp.Open(shapefile)
if err != nil {
fmt.Errorf("UpdateShape err: %v", err)
}
defer shape.Close()
fields := shape.Fields()
return fields
}
複製代碼
shape, err := shp.Open(filepath)
if err != nil {
fmt.Errorf("UpdateShape err: %v", err)
}
defer shape.Close()
fields := shape.Fields()
results := make([]map[string]string, 0)
for shape.Next() {
n, p := shape.Shape()
fmt.Println(n, p, fields, startPageNumber)
if n >= (startPageNumber-1) && n <= (endPageNumber-1) {
var item map[string]string
item = make(map[string]string)
for k, f := range fields {
val := shape.ReadAttribute(n, k)
fmt.Println(n, p, k, f, val)
name := string(f.Name[:])
name = strings.Trim(strings.Replace(name, "\u0000", "", -1), " ")
dec := mahonia.NewDecoder(Encoding)
valutf8 := dec.ConvertString(val)
item[name] = valutf8
}
results = append(results, item)
}
if n >= endPageNumber {
break
}
}
複製代碼
// 讀取shape值
shape, err := shp.Open(ShapeFileName)
if err != nil {
fmt.Errorf("UpdateShape err: %v", err)
}
defer shape.Close()
fields := shape.Fields()
// 新建excel文件
file := xlsx.NewFile()
sheet, _ := file.AddSheet("Sheet1")
// add Header
row := sheet.AddRow()
row.SetHeightCM(1) //設置每行的高度
for k, f := range fields {
cell := row.AddCell()
cell.Value = f.String()
fmt.Println(k)
}
for shape.Next() {
row := sheet.AddRow()
row.SetHeightCM(1) //設置每行的高度
n, p := shape.Shape()
for k, f := range fields {
val := shape.ReadAttribute(n, k)
dec := mahonia.NewDecoder(Encoding)
val = dec.ConvertString(val)
fmt.Println(n, p, k, f, val)
cell := row.AddCell()
// 去除特殊字符
getVal := strings.Replace(val, " ", "", -1)
getVal = strings.Replace(strconv.Quote(getVal), "\x00", "", -1)
getVal = strings.Replace(getVal, "\"", "", -1)
getVal = strings.Replace(getVal, "\\x00", "", -1)
cell.Value = getVal
}
}
//保存excel文件
errXlsx := file.Save("file.xlsx")
複製代碼
下載Excel文件html
後端golang主要代碼:前端
func FileDownload(c *gin.Context, filename string) {
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename)) //fmt.Sprintf("attachment; filename=%s", filename)對下載的文件重命名
c.Writer.Header().Add("Content-Type", "application/octet-stream")
c.File(filename)
}
複製代碼
前端js代碼java
$("#exports").click(function () {
if(shapename == ""){
layer.msg("請先選擇文件")
}else{
window.location.href = "/exports";
}
});
複製代碼
r.GET("/getExcelHead", func(context *gin.Context) {
filename := context.Query("filename")
fmt.Println("filename==" + filename)
type Result struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data map[string]string `json:"data"`
}
var data = make(map[string]string)
data = readExcelHead(filename)
var result Result
result.Code = 0
result.Msg = "success"
result.Data = data
context.JSON(http.StatusOK, result)
})
複製代碼
讀取shape屬性表頭字段:如上GetCols
函數git
Excel和shape字段關聯github
addFields := []shp.Field{}
dictValStr := "#"
for bindKey, bindVal := range obj.AddList {
fmt.Println(bindKey, bindVal, bindVal["newFiledText"], bindVal["bindFiledText"])
newFiledText := bindVal["newFiledText"]
fmt.Println("newFiledText==" + newFiledText)
addFields = append(addFields, shp.StringField(newFiledText, 64))
dictValStr = dictValStr + bindVal["bindFiledText"] + "#"
}
...
複製代碼
shp.UpdateShape(shapeFile, addFields, func(shape *shp.Reader, shapeNew *shp.Writer) {
fieldsObj := shape.Fields()
for shape.Next() {
n, p := shape.Shape()
shapeNew.Write(p)
dictKeyStr = "#"
for key, val := range obj.JoinObj {
fmt.Println(key, val)
shpVal := shape.GetValue(key)
getVal := strings.Replace(shpVal, " ", "", -1)
getVal = strings.Replace(strconv.Quote(getVal), "\x00", "", -1)
getVal = strings.Replace(getVal, "\"", "", -1)
getVal = strings.Replace(getVal, "\\x00", "", -1)
dictKeyStr = dictKeyStr + getVal + "#"
}
for k, f := range fieldsObj {
val := shape.ReadAttribute(n, k)
dec := mahonia.NewDecoder(Encoding)
val = dec.ConvertString(val)
shapeNew.WriteAttribute(n, k, val)
fmt.Println(k, f)
}
teampBindField := dictValStr[1 : len(dictValStr)-1]
bindFileds := strings.Split(teampBindField, "#")
for idx := 0; idx < len(bindFileds); idx++ {
bindFiled := bindFileds[idx]
newVal := DictData[dictKeyStr][bindFiled]
shapeNew.WriteAttribute(n, len(fieldsObj)+idx, newVal)
}
}
})
複製代碼
shp.UpdateShape
是在第三方go-shp 庫擴展而來,主要實現生成新臨時shape文件,並把這個臨時shape文件替換本來的文件。主要代碼以下:func UpdateShape(src string, addFields []Field, callback func(shape *Reader, shapeNew *Writer)) {
var dist string = time.Now().Format("teap_20060102150405") + ".shp"
shape, err := Open(src)
if err != nil {
fmt.Errorf("UpdateShape err: %v", err)
}
defer shape.Close()
// fields to write
fields := shape.Fields()
fields = append(fields, addFields...)
//shapeNew, errNew := shp.Append("test.shp")
shapeNew, errNew := Create(dist, POINT)
if errNew != nil {
fmt.Errorf("UpdateShape err: %v", errNew)
}
defer shapeNew.Close()
shapeNew.SetFields(fields)
//回調函數
callback(shape, shapeNew)
shape.Close()
shapeNew.Close()
distarr := strings.Split(dist, ".")
distName := distarr[0]
srcarr := strings.Split(src, ".")
srcName := srcarr[0]
if len(srcarr) > 2 { // 說明路徑中有多個.
srcName = "."
for i := 0; i < len(srcarr)-1; i++ {
srcName = srcName + srcarr[i]
}
}
shpSrc := srcName + ".shp"
dbfSrc := srcName + ".dbf"
shxSrc := srcName + ".shx"
cpgSrc := srcName + ".cpg"
shpDist := distName + ".shp"
dbfDist := distName + ".dbf"
shxDist := distName + ".shx"
Copy(shpDist, shpSrc)
Copy(dbfDist, dbfSrc)
Copy(shxDist, shxSrc)
//
cpgFileWrite, err := os.Create(cpgSrc)
cpgFileWrite.Write([]byte("UTF-8"))
os.Remove(shpDist)
os.Remove(dbfDist)
os.Remove(shxDist)
}
複製代碼
func Copy(src string, dist string) {
//打開源文件
fileRead, err := os.Open(src)
//fileRead, err := os.Open("C:/itcase/test-視頻.avi")
if err != nil {
fmt.Println("Open err:", err)
return
}
defer fileRead.Close()
//建立目標文件
fileWrite, err := os.Create(dist)
if err != nil {
fmt.Println("Create err:", err)
return
}
defer fileWrite.Close()
//info, _ := os.Stat(src) //Stat獲取文件屬性
//filesize := info.Size()
//從源文件獲取數據,放到緩衝區
buf := make([]byte, 4096)
//循環從源文件中獲取數據,所有寫到目標文件中
for {
n, err := fileRead.Read(buf)
if err != nil && err == io.EOF {
//getProgress(src, filesize, n)
fmt.Printf("讀取完畢,n = d%\n:", n)
return
}
fileWrite.Write(buf[:n]) //讀多少、寫多少
//getProgress(src, filesize, n)
}
}
複製代碼
main.exe
導出
能導出表格數據關聯新增
按鈕,在彈出頁面中,選擇要的excel文件,關聯shape和excel字段;添加新增字段和對應的綁定字段(即excel中的字段),最後點擊保存
按鈕。在執行完畢後,刷新頁面讀取shape列表,檢查是否正確。shape編輯工具工程golang