全国省市区县excel表_xml文件怎么编辑

全国省市区县excel表_xml文件怎么编辑输入是一个xlxs文件,包含所有省市县及其关系和名称要求将至转化为xml并能反应对应的包含关系简介xlxs文件内容如下:包含四个字段,但最后一个字段用不到

输入是一个xlxs文件,包含所有省市县及其关系和名称
要求将至转化为xml并能反应对应的包含关系

简介

xlxs文件内容如下:
节选
包含四个字段,但最后一个字段用不到。

要求转化为形式如下的xml文件:
xml节选

开发步骤

1.选定语言
这里使用了golang语言,常用语言的步骤一定是类似的
2.大致思考开发的主要过程:
经过思考应该包含以下几个部分:
1)解析源文件
2)在内存中进行调整,对层级关系进行调整,生成内存中的对象结构
3)转化为XML形式的字符串
4)新建并写入文件
3.下面对每一个步骤进行操作

解析源文件

考虑这不是一个简单的text文件,这是一个看似是二进制文件的xlxs文件,无法直接解析文件。考虑使用第三方的插件进行解析。
百度“golang xlxs解析”,随便找了一个 文章(点击查看) 。
使用第三方插件的步骤一般就是:1.引入包,2.根据例子了解主要功能的使用方法。
解析完毕的标志就是能够将主要的信息提取出来,使得可以使用程序进行处理。

内存调整

这时候,这个任务就可以看成一个算法题了,已经可以进行抽象处理了。
源数据包括areaID , areaName 和 parentID。
经过大体的查看,发现parentID为0的为省的ID,其ID格式为XX0000,地级市的ID格式为XXXX00,所以可根据这个规律将一行的数据解析为具体是省还是市或者区县。
相关函数如下:

func isProvince(id int) bool { 
   
	str := strconv.Itoa(id) //140000
	if strings.Compare("0000", str[2:]) == 0 { 
   
		return true
	}
	return false
}

func isCity(id int) bool { 
   
	str := strconv.Itoa(id) //140411
	if strings.Compare("0000", str[2:]) != 0 && strings.Compare("00", str[4:]) == 0 { 
   
		return true
	}
	return false
}

下面考虑如何组织出最后的层级结构。
遍历数据表可以得到一组area的信息,包括id,name和parent。
考虑id是唯一的,所以,可以使用散列的方式进行存储,声明出一个1000000(6个零,7位数)的数组,用对应id作为下标存在数组中。
这个对象的结构大概是这样,我们首先将省市县抽象为一种对象Area:

type Area struct { 
   
	areaId     int    
	areaName   string 
	areaParent int    
	areaType   int // 1-p 2-city 3-country
	areaList   []Area
}

其中,省和市会包含下级关系,所以多出一个字段用于存储子结构信息。
因为后面需要判断area类型,使用areaType进行区别

算法步骤如下:
(1 获得area,遍历所有的xlsx的数据行,生成area对象按照ID存在area数组中。
(2 遍历area数组,处理所有的类型为区县的数据,遍历到的area为区县时,将之加到对应的市的areaList中,这里用ID做下标存的用处就来了,可以直接找到所属的市。
(3 再遍历一边area数组,处理所有的地级市,原理和方法与(2类似,将地级市添加到对应的省的areaList中。

理论上已完成了层级关系的处理。

考虑如何转化为xml字符串

经过搜索,我了解到golang内置的xml encode就可以直接将对象转化为xml,只需写好转化后的格式即可,文章随便找了一个 点击查看 。
然后我定义了一下对象,并制订好对应的输出格式:

type AreaList struct { 
   
	ProvinceList []Province `xml:"Province"`
}

type County struct { 
   
	ID       int    `xml:"areaId,attr"`
	Name     string `xml:"areaName,attr"`
	ParentId int    `xml:"-"`
}
type City struct { 
   
	ID       int      `xml:"areaId,attr"`
	Name     string   `xml:"areaName,attr"`
	ParentId int      `xml:"-"`
	Areas    []County `xml:"County"`
}

type Province struct { 
   
	ID    int    `xml:"areaId,attr"`
	Name  string `xml:"areaName,attr"`
	Cites []City `xml:"City"`
}

现在的工作就是想办法完成将刚刚的areaList转化为AreaList,其中不同类型的area转化为Province/City和County。
完成后直接使用一下方法进行转化即可完成字符串的转化:

contentXML, err := xml.Marshal(areaList)

写到文件

最后一步,将上述字符串写到文件中:
继续百度!!随便找了一文章,点击查看 稍微有点坑,他给转化了两边,导致最后生成的文件内容多了一倍的内容。
「注」,哦对,最后生成的文件应该是没有格式化的,在数据传输的角度来看,这无伤大雅,文件可以使用,但是从看的角度和装X的角度的话,额。。。咱要不转化一下?
百度XML格式化工具:随便找一个,点击查看
这回好看咯!!
下面给出所有的源代码:

package main

import (
	"encoding/xml"
	"fmt"
	"github.com/tealeg/xlsx"
	"os"
	"strconv"
	"strings"
)

type AreaList struct { 
   
	ProvinceList []Province `xml:"Province"`
}

type County struct { 
   
	ID       int    `xml:"areaId,attr"`
	Name     string `xml:"areaName,attr"`
	ParentId int    `xml:"-"`
}
type City struct { 
   
	ID       int      `xml:"areaId,attr"`
	Name     string   `xml:"areaName,attr"`
	ParentId int      `xml:"-"`
	Areas    []County `xml:"County"`
}

type Province struct { 
   
	ID    int    `xml:"areaId,attr"`
	Name  string `xml:"areaName,attr"`
	Cites []City `xml:"City"`
}

func main() { 
   
	areaList := AreaList{ 
   
		ProvinceList: ExcelParse2("area.xlsx"),
	}
	contentXML, err := xml.Marshal(areaList)
	if err != nil { 
   
		fmt.Println("err ", err)
	} else { 
   
		WriteWithFileWrite("out.xml", string(contentXML))
	}
}

type Area struct { 
   
	areaId     int    `xml:"areaId"`
	areaName   string `xml:"areaName"`
	areaParent int    `xml:"-"`
	areaType   int // 1-p 2-city 3-country
	areaList   []Area
}

//xlsx文件解析
func ExcelParse2(fileName string) []Province { 
   
	filePath := "upload/" + fileName
	xlFile, err := xlsx.OpenFile(filePath)
	if err != nil { 
   

	}
	//开辟除表头外的行数的数组内存
	provinceArr := make([]Province, 0)
	areaArr := make([]Area, 1000010)
	//遍历sheet
	for _, sheet := range xlFile.Sheets { 
   
		//遍历每一行
		for rowIndex, row := range sheet.Rows { 
   
			//跳过第一行表头信息
			if rowIndex == 0 { 
   
				continue
			}
			//遍历每一个单元
			id, _ := row.Cells[0].Int()
			name := row.Cells[1].String()
			parent, _ := row.Cells[2].Int()
			aarea := Area{ 
   
				areaId:     id,
				areaName:   name,
				areaParent: parent,
			}
			if isProvince(id) { 
   
				aarea.areaType = 1
				//areass = append(areass, p)
			} else if isCity(id) { 
   
				aarea.areaType = 2
				//areass[id] = c
				//areass = append(areass, c)
			} else { 
   
				aarea.areaType = 3
				//areass = append(areass, a)
			}
			areaArr[aarea.areaId] = aarea

		}
	}

	//第一遍扫描将所有的Country放在City类型里
	for _, coun := range areaArr { 
   
		if coun.areaType == 3 { 
   
			areaArr[coun.areaParent].areaList = append(areaArr[coun.areaParent].areaList, coun)
		}
	}
	//第二遍扫描将所有的City放在Province类型中
	for _, ci := range areaArr { 
   
		if ci.areaType == 2 { 
   
			areaArr[ci.areaParent].areaList = append(areaArr[ci.areaParent].areaList, ci)
		}
	}
	//生成返回数组
	for _, p := range areaArr { 
   
		if p.areaType == 1 { 
   
			citys := make([]City, 0)
			for _, c := range p.areaList { 
   
				countrys := make([]County, 0)
				for _, a := range c.areaList { 
   
					countrys = append(countrys, County{ 
   
						ID:   a.areaId,
						Name: a.areaName,
					})
				}
				citys = append(citys, City{ 
   
					ID:    c.areaId,
					Name:  c.areaName,
					Areas: countrys,
				})
			}
			provinceArr = append(provinceArr, Province{ 
   ID: p.areaId, Name: p.areaName, Cites: citys})
		}
	}

	return provinceArr
}


func isProvince(id int) bool { 
   
	str := strconv.Itoa(id) //140411
	if strings.Compare("0000", str[2:]) == 0 { 
   
		return true
	}
	return false
}

func isCity(id int) bool { 
   
	str := strconv.Itoa(id) //140411
	if strings.Compare("0000", str[2:]) != 0 && strings.Compare("00", str[4:]) == 0 { 
   
		return true
	}
	return false
}

//
//func isArea(id int) bool { 
   
// if !isProvince(id) && !isCity(id) { 
   
// return true
// }
// return false
//}

func WriteWithFileWrite(name, content string) { 
   
	fileObj, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil { 
   
		fmt.Println("Failed to open the file", err.Error())
		os.Exit(2)
	}
	defer fileObj.Close()
	if _, err := fileObj.WriteString(content); err == nil { 
   
		fmt.Println("Successful writing to the file with os.OpenFile and *File.WriteString method.", content)
	}
	
}

今天的文章全国省市区县excel表_xml文件怎么编辑分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/81497.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注