golang解析excelcsv编码格式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang解析excelcsv编码格式相关的知识,希望对你有一定的参考价值。

开箱即用的工具

前言

比如 utf8gbkGB18030

excel和csv中有多种编码格式,也是比较头疼的。这里提供多种解析方式。开箱即用的工具

源码

// 转为utf8格式
ConvertToString("你的字符")

package utils

import (
	"github.com/axgle/mahonia"
	"golang.org/x/text/encoding/simplifiedchinese"
)

const (
	GBK     string = "GBK"
	UTF8    string = "UTF8"
	UNKNOWN string = "UNKNOWN"
)

func ConvertToStringByCode(src string, srcCode string, tagCode string) string 
	srcCoder := mahonia.NewDecoder(srcCode)
	srcResult := srcCoder.ConvertString(src)
	tagCoder := mahonia.NewDecoder(tagCode)
	_, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
	result := string(cdata)
	return result


func ConvertToStringGbkToUtf8(src string) string 
	if isUtf8([]byte(src)) 
		return src
	
	var srcCode = "gbk"
	var tagCode = "utf-8"
	srcCoder := mahonia.NewDecoder(srcCode)
	srcResult := srcCoder.ConvertString(src)
	tagCoder := mahonia.NewDecoder(tagCode)
	_, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
	result := string(cdata)
	return result


func ConvertToString(src string) string 
	if isUtf8([]byte(src)) 
		return src
	
	if isGBK([]byte(src)) 
		utf8Data, err := simplifiedchinese.GBK.NewDecoder().Bytes([]byte(src))
		if err != nil 
			return src
		
		if isUtf8(utf8Data) 
			return string(utf8Data)
		 else 
			return ConvertToStringGbkToUtf8(string(utf8Data))
		
	
	sink, err := simplifiedchinese.GB18030.NewDecoder().Bytes([]byte(src))
	if err != nil 
		return src
	
	return string(sink)


func isGBK(data []byte) bool 
	length := len(data)
	var i int = 0
	for i < length 
		if data[i] <= 0x7f 
			//编码0~127,只有一个字节的编码,兼容ASCII码
			i++
			continue
		 else 
			//大于127的使用双字节编码,落在gbk编码范围内的字符
			if data[i] >= 0x81 &&
				data[i] <= 0xfe &&
				data[i+1] >= 0x40 &&
				data[i+1] <= 0xfe &&
				data[i+1] != 0xf7 
				i += 2
				continue
			 else 
				return false
			
		
	
	return true


func preNUm(data byte) int 
	var mask byte = 0x80
	var num int = 0
	//8bit中首个0bit前有多少个1bits
	for i := 0; i < 8; i++ 
		if (data & mask) == mask 
			num++
			mask = mask >> 1
		 else 
			break
		
	
	return num


func isUtf8(data []byte) bool 
	i := 0
	for i < len(data) 
		if (data[i] & 0x80) == 0x00 
			// 0XXX_XXXX
			i++
			continue
		 else if num := preNUm(data[i]); num > 2 
			// 110X_XXXX 10XX_XXXX
			// 1110_XXXX 10XX_XXXX 10XX_XXXX
			// 1111_0XXX 10XX_XXXX 10XX_XXXX 10XX_XXXX
			// 1111_10XX 10XX_XXXX 10XX_XXXX 10XX_XXXX 10XX_XXXX
			// 1111_110X 10XX_XXXX 10XX_XXXX 10XX_XXXX 10XX_XXXX 10XX_XXXX
			// preNUm() 返回首个字节的8个bits中首个0bit前面1bit的个数,该数量也是该字符所使用的字节数
			i++
			for j := 0; j < num-1; j++ 
				//判断后面的 num - 1 个字节是不是都是10开头
				if (data[i] & 0xc0) != 0x80 
					return false
				
				i++
			
		 else 
			//其他情况说明不是utf-8
			return false
		
	
	return true


func GetStrCoding(data []byte) string 
	if isUtf8(data) == true 
		return UTF8
	 else if isGBK(data) == true 
		return GBK
	 else 
		return UNKNOWN
	


以上是关于golang解析excelcsv编码格式的主要内容,如果未能解决你的问题,请参考以下文章

GoLang -- json文件操作

#yyds干货盘点#Golang 编码和解析Json

golang 日期时间字符串处理支持多种格式(应对日期反序列化问题)

golang编码规范

golang UTF8转中文字符

Golang中进行Url编码,再也不怕奇奇怪怪的参数格式了