一般导出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;
}
相关推荐
标题中的"Spreadsheet-WriteExcel-2.15.tar.rar"是一个软件库的打包文件,主要用于Perl语言,目的是为了能够创建和写入Excel文件。这个版本是2.15,通常意味着它包含了该库的最新功能和修复。".tar"和".rar"都是压缩...
Spreadsheet::WriteEXcel安装包 下载 Spreadsheet-WriteExcel-2.40.tar.gz并解压在DBI-1.13中 和安装cpan一样,在目录中执行以下操作: perl Makefile.PL make make test make install make clean
除了这两个主要模块,还有一些其他的Perl模块扩展了Spreadsheet的功能,如Spreadsheet::ParseXLSX用于处理.xlsx格式,Spreadsheet::WriteExcel::Utilities提供了一些辅助功能,比如将数组转换成Excel格式。...
Spreadsheet-ParseExcel,Perl的Excel插件,可用于读写Excel文件,在Linux下对...可以用Spreadsheet::ParseExcel先解析excel,再用Spreadsheet::WriteExcel写入。 或者直接使用Spreadsheet::ParseExcel::SaveParser。
Perl SpreadSheet_Excel 是一个基于Perl编程语言的库,用于解析和操作Microsoft Excel电子表格文件。这个库的核心组件是 `...通过 `Spreadsheet::WriteExcel` 这样的配套模块,还可以实现Excel文件的写入功能。
除了这两个核心模块,还有其他一些扩展模块,如Spreadsheet::WriteExcel::Simple用于简化写入过程,或者Spreadsheet::XLSX::Reader::Simple用于简化读取过程。这些模块可以帮助开发者更高效地处理Excel文件。 在...
这些库主要是Spreadsheet::WriteExcel和Spreadsheet::ParseExcel,它们为Perl开发者提供了方便的API,使得在不依赖Microsoft Office的情况下,也能处理Excel数据。 1. **Spreadsheet::WriteExcel**: 这个模块允许...
在Perl中,你可以使用Spreadsheet::ParseXLSX或Spreadsheet::WriteExcel等子模块来处理Microsoft Excel格式的文件。例如,你可以读取一个现有的Excel文件,修改其中的数据,然后重新保存。这对于数据分析、报告生成...
对于需要与Microsoft Office 2007及以上版本兼容的.xlsx格式文件交互的任务,Perl社区提供了多个库,其中“Excel::Writer::XLSX”是处理.xlsx文件的首选工具之一。 #### 核心知识点详解: ##### Excel::Writer::...
Perl提供了多种库来处理这种任务,其中最常用的是Spreadsheet::ParseXLSX和Spreadsheet::WriteExcel。 1. **Spreadsheet::ParseXLSX**:这是Perl中用于读取Excel 2007及以上版本(.xlsx文件)的库。它不依赖...
2. Spreadsheet::WriteExcel:这是一个用于创建老版 Excel 文件(.xls)的模块。如果你需要生成新的 Excel 文件或向现有文件写入数据,这个模块将派上用场。它可以创建工作表、格式化单元格、添加公式等。 在实际...
描述中提到的"for linux perl, can read and write for excel file, very easy to use it"意味着这个模块在Linux操作系统下运行,并且具备读写Excel文件的能力。Perl是一种跨平台的脚本语言,因此Spreadsheet::...
例如,`Office::ParseXLS`模块用于解析Excel文件,而`Spreadsheet::WriteExcel`模块则可以用来创建新的Excel文件或者写入数据到已有的Excel文件中。对于Word文档,`Win32::OLE`模块允许通过COM接口与Word应用程序...
`Spreadsheet::WriteExcel`是一个用于创建Microsoft Excel (XLS)工作簿的Perl模块。它可以创建纯Excel 95/97/2000/2003文件,不需要安装任何其他软件或库。该模块支持多种功能,包括但不限于: - 创建新的Excel文件...
5. **广泛支持**:Perl社区庞大,有大量的模块和资源可供使用,包括处理Excel的其他模块如Spreadsheet::WriteExcel、Spreadsheet::ParseExcel等,为开发者提供了丰富的选择。 **使用Win32::OLE模块操作Excel的基本...
set workbook [::Spreadsheet::WriteExcel::new "example.xls"] ``` 然后,向工作簿中添加工作表: ```tcl set worksheet [$workbook addWorksheet "Sheet1"] ``` 接着,写入数据到工作表中: ```tcl $worksheet ...
在Perl编程语言中,虽然有多种处理Excel文件的模块,如Spreadsheet::WriteExcel,但对于已经习惯使用Qt库的开发者来说,QTxlsx可能是一个更自然的选择,特别是当他们的项目已经依赖于Qt库时。 Perl是一种功能强大的...
例如,`Text::CSV`模块用于读取和写入CSV文件,而`Spreadsheet::WriteExcel`或`Excel::Writer::XLSX`模块则用于创建Excel文件。以下是一个基本的流程概述: 1. **数据提取**: - 使用`Text::CSV`打开和解析数据...
该库是从Perl的Spreadsheet :: WriteExcel模块转换而来的。 / 原始说明如下: The Spreadsheet::WriteExcel module can be used to create a cross- platform Excel binary file. Multiple worksheets can be ...
Perl的`Spreadsheet`模块如`Spreadsheet::WriteExcel`或`Spreadsheet::ParseExcel`可以帮助将数据转化为符合标准格式的报表,例如将数据导出为MIS系统所需的格式。这样可以避免手动操作,减少错误并提高效率。 3. *...