Perl之Spreadsheet::WriteExcel
一般导出excel功能是出现在后台管理系统中,运营人员为了便于统计,经常需要将大量数据导出。
本文主要描述如何将mongodb查询出来的数据写入excel表格。
一、安装相关模块:
1、MongoDB -> 操作数据库
接口文档https://metacpan.org/pod/distribution/MongoDB/lib/MongoDB/Tutorial.pod
2、Spreadsheet::WriteExcel -> 操作excel
接口文档https://metacpan.org/pod/Spreadsheet::WriteExcel
3、Try::Tiny -> try-catch功能
4、Safe::Isa -> try-catch功能
安装方法:
sudo perl -MCPAN -e 'install MongoDB'
sudo perl -MCPAN -e 'install Spreadsheet::WriteExcel'
或者
perl -MCPAN -e shell
cpan[1]> install MongoDB
或者
下载源码包MongoDB-v1.4.5.tar.gz
解压tar xvf MongoDB-v1.4.5.tar.gz,
cd MongoDB-v1.4.5/
perl Makefile.PL
make
make install
二、本文方案
web前端将运营者的输入条件POST给服务端的CGI脚本,CGI脚本解析请求后,根据规则查表,写入excel,同时将excel文件放到可下载的目录,完成后返回下载链接给web前端。
三、代码片段
对于一个后台管理系统,可能会在很多地方需要用到导出excel功能,而且运营者通常需要加入查询/过滤条件,同时只要求返回特定的字段。所以,本文尽量写个通用的版本,以供参考。
#excel.pl - CGI脚本
use warnings;
use utf8;
binmode(STDIN, ':encoding(utf8)');
binmode(STDOUT, ':encoding(utf8)');
binmode(STDERR, ':encoding(utf8)');
==》 以上解决中文问题(要求数据库表里的内容也是utf8格式)
use CGI;
use JSON; #解析web前端的post请求
use Encode; #查询条件可能带中文,需要utf8编码
use MongoDB;
use Try::Tiny;
use Safe::Isa;
use Spreadsheet::WriteExcel;
use Time::HiRes qw(gettimeofday usleep);
use Data::Dumper;
my $OUTPUT = '{"file_path":"", "status":"failed"}'; #返回给web前端的结果
my $DOWNLOAD_ROOT = "/tmp/download"; #excel文件所在目录
my $DB_NAME = "TEST";
my $DB_OPTIONS = {
username => "db",
password => "123"
};
my $DB_HOSTS = "mongodb://localhost"; # 默认mongodb装在本机,端口号27017, 也可以是ip加端口号"mongodb://116.5.100.152:27000", 具体参考MongoDB的接口文档
$ROW_COLUM_SET = { #表格设置
abc_list => { #对应后台的某个功能
collection => "abc", #对应表名称
search => { #查询条件
title => {db_key => "title", regex => "true"}, #db_key对应数据库字段, format是否正则匹配方式
day => {db_key => "start_time", regex => "false"},
default_query => {tag=> "myself"} #默认的查询条件
},
row_colum => { #表头设置
"ID" => {db_key => "_id", format => "string"}, #db_key对应数据库字段, format字段数据类型
"标题" => {db_key => "title", format => "string"},
"图片" => {db_key => "image_fid", format => "string"},
"链接" => {db_key => "url", format => "string"},
"时间" => {db_key => "start_time", format => "time"}
}
},
xyz_list => { #对应后台的某个功能
collection => "xyz", #对应表名称
search => { #查询条件
person_account => {db_key => "person_account", regex => "true"},
status => {db_key => "exchge_status", regex => "false"}
},
row_colum => {
"记录ID" => {db_key => "_id", format => "string"}
"日期" => {db_key => "et", format => "time"},
"用户号码" => {db_key => "person_account", format => "string"}
"状态" => {db_key => "status", format => "string"}
},
special_func => \&xyz_list #需要调用特定函数处理(函数指针方式)
}
};
###CGI处理POST请求####
# web前端post过来的数据: {"methond":"abc_list", "search_condition":{"title":"历史"}}
if ($cgi->param("POSTDATA")) {
my $post_data = $cgi->param("POSTDATA");
my $input_json = $json->decode($post_data);
my $methond = $input_json->{methond};
if (length($methond) ) {
if (!$ROW_COLUM_SET->{$methond}) {
write_log("input.log", "Not implement: $methond");
print_result($OUTPUT);
}
#连接数据库
my $client;
my $db;
try {
$client = MongoDB->connect($DB_HOSTS, $DB_OPTIONS);
} catch {
if ( $_->$_isa("MongoDB::AuthError" ) ) {
write_log("db.log", "MongoDB::AuthError");
} elsif ( $_->$_isa("MongoDB::ConnectionError" ) ) {
write_log("db.log", "MongoDB::ConnectionError");
}
print_result($OUTPUT);
};
try {
$db = $client->get_database($DB_NAME );
} catch {
if ( $_->$_isa("MongoDB::DatabaseError" ) ) {
write_log("db.log", "MongoDB::DatabaseError");
}
print_result($OUTPUT);
};
#获取数据
my $collection = $ROW_COLUM_SET->{$methond}->{collection};
my $search = $ROW_COLUM_SET->{$methond}->{search};
write_log("db.log", "Set Query hash of $collection");
my $queryHash;
foreach my $cod (keys %{$search}) {
if ($cod eq "default_query") { #默认查询条件赋值
foreach my $k (keys %{ $search->{$cod} }) {
$queryHash->{$k} = $search->{$cod}->{$k};
}
} elsif (length($input_json->{search_condition}->{$cod})) { #前端输入的查询条件
#处理中文
my $value = Encode::decode("utf-8", $input_json->{search_condition}->{$cod});
my $db_key = $search->{$cod}->{db_key};
$queryHash->{$db_key} = $value;
if ($search->{$cod}->{db_key} eq "true") { #需要正则匹配
$queryHash->{$db_key} = {'$regex'=> $value};
}
}
}
my @result = (); #数据放入数组中
#是否需要调用特定函数来查询, 利用了函数指针
my $func_ref = $ROW_COLUM_SET->{$methond}->{special_func};
if ((ref($func_ref) eq "CODE") && defined(&{$func_ref}) ) {
@result = &{$func_ref}($db, $queryHash); #调用特定函数查询
} else {
my $mocl = $db->get_collection($collection)->find($queryHash);
@result = $mocl->all();
}
#填充表格
my $FILE_ID = time().int(rand(10000)).".xls"; #生成一个随机名字
my $xls_name = "$DOWNLOAD_ROOT/$FILE_ID";
my $workbook = Spreadsheet::WriteExcel->new($xls_name);
$worksheet = $workbook->add_worksheet();
write_log("db.log", "---Start write---\n");
#写标题
my $row_colum = $ROW_COLUM_SET->{$methond}->{row_colum};
my $colum_id = 0;
foreach my $k (keys %{ $row_colum }) {
$worksheet->write(0, $colum_id, $k); #写入第一行
$colum_id++; #列递增
}
write_log("db.log", "Finish wirte title\n");
#写内容
my $row_id = 1; #从第二行开始
foreach my $obj (@result) {
next if(!$obj);
$colum_id = 0;
foreach my $k (keys %{ $row_colum }) {
my $db_key = $row_colum->{$k}->{db_key};
my $content = $obj->{$db_key};
if (length($content) == 0) {
$content = "NULL";
} elsif ($row_colum->{$k}->{format} eq "time") { #数据类型处理
$content = formateTime($content);
} elsif ($row_colum->{$k}->{format} eq "float") {#数据类型处理
$content = formateFloat($content);
}
$worksheet->write($row_id, $colum_id, $content);
$colum_id++;
}
$row_id++;
}
$workbook->close();
my $file_path = "http://xxx/$FILE_ID";
$OUTPUT = '{"file_path":"'.$file_path.'", "status":"success"}'; #输出结果
print_result($OUTPUT);
}
}
exit;
#########################相关子函数#####################
sub print_result {
my $output = $_[0];
print "Access-Control-Allow-Origin: *\r\n";
print "Content-Type: application/json\r\n\r\n";
print $output;
exit;
}
sub formateTime {
my $time1 = $_[0] + 0;
my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime($time1);
$year = $year + 1900;
$month = $month + 1;
return "$year/$month/$day $hour:$min:$sec";
}
sub formateFloat {
my $float = $_[0];
$float = sprintf("%.2f", $float);
return $float;
}
sub xyz_list {
my ($db, $query_hash) = @_;
my @result_list = ();
....
return @result_list;
}
Perl之Spreadsheet::WriteExcel相关推荐
- Perl之Spreadsheet::WriteExcel安装
本文主要描述如何在linux系统下安装cpan以及安装WriteExcel插件,将perl读取出来的数据写入excel表格. 首先会报出如下错误: Can't locate Spreadsheet/P ...
- perl处理Excel(跨平台)
前言 更多内容,请访问我的 个人博客. 前言 用perl处理excel有两种流行的模块:一种是 win32:OLE 模块,优点是功能强大,在excel上能做的事情用这个模块都能做,缺点是无法跨平台,必 ...
- Perl读写Excel简单操作
Perl读写Excel简单操作 使用模块 Spreadsheet::ParseExcel Spreadsheet::WriteExcel 读Excel #!/usr/bin/perl -wuse st ...
- 功能丰富的Perl:用Perl读写Excel文件
功能丰富的Perl:用Perl读写Excel文件 2001年08月31日 16:00 来源:ChinaUnix文档频道 作者:HonestQiao 编辑:周荣茂 级别: 初级 Teodor Zlata ...
- 操作excel的perl模块
CPAN上提供了Spreadsheet::WriteExcel 和 Spreadsheet::ParseExcel这两个模块.下面我们就来看看Spreadsheet::WriteExcel 和 Spr ...
- Perl操作excel2007的模块
详细版:https://www.jianshu.com/p/84bda53827c8 第一种方法: 读写excel2007文档的perl模块: Spreadsheet::XLSX(读)和Spreads ...
- Spreadsheet电子表格控件安装及用法总结
Spreadsheet是一个用来查看和编辑Excel电子表格文件的控件,它可用在类似Excel的界面上.它结合了很多我们最流行的部件,像网格控件,Ribbon组件,公式引擎,还有很多其他控件.旨在创建 ...
- 找了好久的perl在window上读excel的脚本
清单 1:安装 Excel 模块的 PPM 命令 ppm> install OLE::Storage_Lite ppm> install Spreadsheet::ParseExcel p ...
- Perl脚本实现tiptop数据导出EXCEL模板
在tiptop上利用Perl 脚本,实现按自定义格式导出Excel模板数据,支持多页签 实现方式,先将Perl脚本放到服务器,赋予正确权限,程序先将数据按指定格式写入TXT文档,最后,利用Perl脚本 ...
最新文章
- Iframe 用法浅析
- 技术沙龙 | TeaTalk 带你深度探索 SDN 网络技术再创新
- 问卷星调查学生对《算法》教学的建议与反馈
- Java 源代码和 C 源代码的运行区别
- 基于MSM 的tomcat session 共享
- 网络数据包信息收集工具ferret-sidejack
- 【LDA学习系列】LDA-Python库
- 清华大学计算机图形学课程
- php监控系统,php 系统监控 | 学步园
- php中的缓,php中的缓存机制解释
- android用kotlin制作计算器,使用Kotlin做一个简单计算器
- python input 与raw_input函数的区别
- Eclipse Tips(2):代码颜色设置
- html调用矢量小图标的方法,微信小程序里引入SVG矢量图标的方法
- html 图标制作,icon小图标制作
- 优启通安装linux系统,利用U盘启动盘优启通(pe)安装centos到旧笔记本上
- vdbench 配置案例及参数说明
- C语言程序设计-餐厅点餐系统
- dubbo的底层原理
- Linux 基础上篇