goalng导出excel(csv格式)
最近项目中有个小需求,需要将查询结果导出到excel。之间前java比较容易,使用POI很容易就能实现,查了下golang的文档,发现golang下边并没有导出excel的包,但是却有一个encoding/csv的包,看了下发现可以导出csv文件,大家都知道csv文件其实就是文本格式的excel文件,可以直接通过excel打开或是导入excel。
看起来挺好的,问题如愿解决,但是事实证明对已一个还不成熟的语言或是库最好还是先测一下的好。兴冲冲的卸了测试例子,成功导出了一个text.csv文件,一切看起来都挺好的,然而打开之后就傻眼了:中文乱码,这个问题其实比较好理解,golang只支持utf-8,而win中文版默认字符集是GB2312(gbk),这样看来直接转码就行了呗。
由于之前吃了亏,这次我们先直接报文件转下码试试:直接将之前导出的text.csv另存为ASCII格式,打开后发现回车换行符丢了,全部变成一行了。这下就郁闷了,先看下源码吧:
// Writer writes a single CSV record to w along with any necessary quoting.
// A record is a slice of strings with each string being one field.
func (w *Writer) Write(record []string) (err error) {
for n, field := range record {
if n > 0 {
if _, err = w.w.WriteRune(w.Comma); err != nil {
return
}
} // If we don't have to have a quoted field then just
// write out the field and continue to the next field.
if !w.fieldNeedsQuotes(field) {
if _, err = w.w.WriteString(field); err != nil {
return
}
continue
}
if err = w.w.WriteByte('"'); err != nil {
return
} for _, r1 := range field {
switch r1 {
case '"':
_, err = w.w.WriteString(`""`)
case '\r':
if !w.UseCRLF {
err = w.w.WriteByte('\r')
}
case '\n':
if w.UseCRLF {
_, err = w.w.WriteString("\r\n")
} else {
err = w.w.WriteByte('\n')
}
default:
_, err = w.w.WriteRune(r1)
}
if err != nil {
return
}
} if err = w.w.WriteByte('"'); err != nil {
return
}
}
if w.UseCRLF {
_, err = w.w.WriteString("\r\n")
} else {
err = w.w.WriteByte('\n')
}
return
}
可以看到代码十分简单,每行就是按照csv的格式写入文件而已。需要注意的是writer里边有一个UserCRLF来指定是否适应回车换行符,默认为false,问题应该就出在这里,但是将UserCRLF设置为true之后,问题依旧,看来是转码有问题。
既然代码这么简单,那么还不如直接自己实现,然后转码输出,这里使用iconv-go进行转码,实现如下:
package components import (
"bytes"
"errors"
iconv "github.com/djimenez/iconv-go"
) /**
* 导出处理
*/ const (
OUT_ENCODING = "gbk" //输出编码
) /**
* 导出csv格式文件,输出byte数组
* 输出编码通过OUT_ENCODING指定
*/
func ExportCsv(head []string, data [][]string) (out []byte, err error) {
if len(head) == 0 {
err = errors.New("ExportCsv Head is nil")
return
} columnCount := len(head)
dataStr := bytes.NewBufferString("")
//添加头
for index, headElem := range head {
separate := ","
if index == columnCount-1 {
separate = "\n"
}
dataStr.WriteString(headElem + separate)
} //添加数据行
for _, dataArray := range data {
if len(dataArray) != columnCount { //数据项数小于列数
err = errors.New("ExportCsv data format is error.")
}
for index, dataElem := range dataArray {
separate := ","
if index == columnCount-1 {
separate = "\n"
}
dataStr.WriteString(dataElem + separate)
}
} //处理编码
out = make([]byte, len(dataStr.Bytes()))
iconv.Convert(dataStr.Bytes(), out, "utf-8", OUT_ENCODING)
return
}
测试一下,导出成功,而且没有乱码问题。
对于目前这个项目而言,导出简单格式的csv就能满足,但是如果想导出复杂的excel文件就不行了。考虑了下大概想出了以下几种方法:
- 使用cgo,用c来实现导出,这是golang处理类似问题的一贯作风,然而就导出excel而言并不太好,因为c导出复杂格式的excel本身就挺麻烦的
- 调用其他语言实现的模块,至于怎么调就无所谓,如果对于大批量的导出,其实还挺好的,可以把生成excel这样费时费力的操作给分离出去
- 按照excel文件格式直接生成为对应二进制文件,这个实现起来可能比较费劲,但是确实一劳永逸的,这里附一个excel格式的链接,有兴趣的可以实现下。
goalng导出excel(csv格式)的更多相关文章
- (转载)DBGridEh导出Excel等格式文件
DBGridEh导出Excel等格式文件 uses DBGridEhImpExp; {--------------------------------------------------------- ...
- PHP 高效导入导出Excel(csv)方法之fgetcsv()和fputcsv()函数
CSV,是Comma Separated Value(逗号分隔值)的英文缩写,通常都是纯文本文件. 一.CSV数据导入函数fgetcsv() fgetcsv() 函数从文件指针中读入一行并解析 CSV ...
- Elasticsearch:如何把Elasticsearch中的数据导出为CSV格式的文件
本教程向您展示如何将数据从Elasticsearch导出到CSV文件. 想象一下,您想要在Excel中打开一些Elasticsearch中的数据,并根据这些数据创建数据透视表. 这只是一个用例,其中将 ...
- AX导出excel设置格式
今天在AX2009里面写一个导出EXCEL,没有模版,这是第一次碰到,之后写完之后发现导出的数据格式不对. 到处取经之后得到一下结果: 定义一个 Com range; SysExcelCells ...
- POI导入导出Excel(HSSF格式,User Model方式)
1.POI说明 Apache POI是Apache软件基金会的开源代码库, POI提供对Microsoft Office格式档案读和写的功能. POI支持的格式: HSSF - 提供读写Microso ...
- 将数据 导出excel表格式
我的考试完提交生成的数据 这是我的考试题类型 //导出调查评议的数据 public function diaocha(){ $xlsName = '表格形式 调查评议 信息'; $xlsTitle = ...
- Asp.net导出Excel/Csv文本格式数据
刚刚开始做Excel相关的项目,所以遇到的问题不管大小都给记录一下 偶然的机会在添加数据的时候全改成了数字,结果输出的时候全自动变成了科学计数法,这是excel的强大功能,能自动识别数字和字符串,太聪 ...
- mongodb导出数据csv格式
mongoexport -d test -c item --type=csv -f salary,city,workYear,companyShortName -o user.csvmongoexpo ...
- c# 导入导出excel表格式
c#使用代码导入excel时,当遇到纯数字且大于15位时会出现编码混乱(表现为科学计数法),要想呈现与excel表中纯数字格式和在数据库中呈现纯数字,操作如下: 完成即可. 导出取决于导入的内容排版.
随机推荐
- PSS下载助手(PSX Download Helper)1.7.6.1发布
新增自动查找本地替换文件,让替换大法也更简单的计划…… 使用方法很简单,首先进入设置勾选“自动查找替换文件”,然后点击“选择目录”,最后保存设置即可.将文件下载至你选择的目录中,然后再次在主机/掌机端 ...
- rabbitmq 不发送ack消息如何处理:rabbitmq可靠发送的自动重试机制
转载地址:http://www.jianshu.com/p/6579e48d18ae http://www.jianshu.com/p/4112d78a8753 接这篇 在上文中,主要实现了可靠模式的 ...
- Redis的数据类型(lists、Sets)
lists类型 Redis 列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素到列表的头部(左边)或者尾部(右边) LPUSH 命令插入一个新的元素到头部, 而 RPUSH 插入一个新元素导 ...
- 1、http简介
HTTP 简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传 ...
- 1.2 the structure of a compiler
Compiler 1.2 the structure of a compiler Compiler : analysis and synthesis syntactically 语法上的 sema ...
- python+selenium之多表单切换
在Web应用中经常会遇到fram/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于fram/iframe表单内嵌套页面上的元素无法直接定位.这是需要通过swit ...
- 使用jmeter测试数据库性能
出现如图所示的问题 解决办法: 1.下载驱动包,将mysql-connector-Java.jar分别放到Jmeter和Java安装目录的lib和ext目录下 链接:http://pan.baidu. ...
- GWTDesigner_v5.1.0破解码
GWTDesigner_v5.1.0_win32_x86.exe破解码,双击运行keygeno.jar,然后输入用户名.网卡MAC,然后单击Generate,将生成的文件放在C:\Documents ...
- codeforce Gym 100570B ShortestPath Query (最短路SPFA)
题意:询问单源最短路径,每条边有一个颜色,要求路径上相邻边的颜色不能相同,无重边且边权为正. 题解:因为路径的合法性和边的颜色有关, 所以在做spfa的时候,把边丢到队列中去,松弛的时候注意判断一下颜 ...
- zend studio failed to create java virtual machine无法启动的解法
zend studio failed to create java virtual machine 解决方案:在安装目录下修改ZendStudio.ini中第十四行处改成 -Xmx512M. -sta ...