我是perl的新手。 我有一个包含大量数据的Excel表格。我需要更新它并根据数据创建图表。使用perl。 我成功更新了现有的excel .. 现在添加图表没有发生
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::SaveParser;
use Spreadsheet::WriteExcel;
# Open an existing file with SaveParser
my $parser = Spreadsheet::ParseExcel::SaveParser->new();
my $template = $parser->Parse('MyExcel.xls');
my $worksheet = $template->worksheet('Firstsheet');
my $chart = $template->add_chart( type => 'line' );
$chart->add_series(
categories => '=URV!$A$17:$A$442',
values => '=URV!$D$17:$D$442',
name => 'pended graph',
);
这不起作用。 无法调用方法" add_chart"在chart4.ps第20行的未定义值 请帮我一个示例工作代码.. 想知道这里的问题是什么。
答案 0 :(得分:1)
add_chart()是WORKBOOK方法之一。尝试这样的代码:
use Spreadsheet::WriteExcel;
my $workbook = Spreadsheet::WriteExcel->new('perl.xls');
$worksheet = $workbook->add_worksheet();
$worksheet->write('A1', 'Hi Chart!');
my $chart = $workbook->add_chart( type => 'line', embedded => 1, name => 'pended graph' );
# Insert the chart into the a worksheet.
$worksheet->insert_chart( 'E2', $chart );
<强>更新强>
问题是使用perl很难更新excel。
Excel文件是二进制文件中的二进制文件。它包含 几个相互关联的校验和甚至改变一个字节都可能导致它 变得腐败。
因此,您不能简单地附加或更新Excel文件。唯一的办法 实现这一点就是将整个文件读入内存,制作出来 需要更改或添加,然后再次写出文件。
Spreadsheet :: ParseExcel将读入现有的excel文件:
my $parser = Spreadsheet::ParseExcel->new();
# $workbook is a Spreadsheet::ParseExcel::Workbook object
my $workbook = $parser->Parse('blablabla.xls');
你真正想要的是 Spreadsheet :: ParseExcel :: SaveParser ,它是 Spreadsheet :: ParseExcel 和 Spreadsheet :: WriteExcel 。
总结一下,我建议你阅读excel数据,然后尝试以下任何一种方法:
如果您使用的是Windows计算机,则可以尝试使用 Win32 :: OLE 。 以下是 Win32 :: OLE 自己的文档中的示例:
use Win32::OLE;
# use existing instance if Excel is already running
eval {$ex = Win32::OLE->GetActiveObject('Excel.Application')};
die "Excel not installed" if $@;
unless (defined $ex) {
$ex = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;})
or die "Oops, cannot start Excel";
}
# get a new workbook
$book = $ex->Workbooks->Add;
# write to a particular cell
$sheet = $book->Worksheets(1);
$sheet->Cells(1,1)->{Value} = "foo";
# write a 2 rows by 3 columns range
$sheet->Range("A8:C9")->{Value} = [[ undef, 'Xyzzy', 'Plugh' ],
[ 42, 'Perl', 3.1415 ]];
# print "XyzzyPerl"
$array = $sheet->Range("A8:C9")->{Value};
for (@$array) {
for (@$_) {
print defined($_) ? "$_|" : "<undef>|";
}
print "\n";
}
# save and exit
$book->SaveAs( 'test.xls' );
undef $book;
undef $ex;
<强> UPDATE @ 2 强>
以下是一个示例代码:
use strict;
use Spreadsheet::WriteExcel;
my $workbook = Spreadsheet::WriteExcel->new( 'chart_column.xls' );
my $worksheet = $workbook->add_worksheet();
my $bold = $workbook->add_format( bold => 1 );
# Add the worksheet data that the charts will refer to.
my $headings = [ 'Category', 'Values 1', 'Values 2' ];
my $data = [
[ 2, 3, 4, 5, 6, 7 ],
[ 1, 4, 5, 2, 1, 5 ],
[ 3, 6, 7, 5, 4, 3 ],
];
$worksheet->write( 'A1', $headings, $bold );
$worksheet->write( 'A2', $data );
###############################################################################
#
# Example 1. A minimal chart.
#
my $chart1 = $workbook->add_chart( type => 'column', embedded => 1 );
# Add values only. Use the default categories.
$chart1->add_series( values => '=Sheet1!$B$2:$B$7' );
# Insert the chart into the main worksheet.
$worksheet->insert_chart( 'E2', $chart1 );
###############################################################################
#
# Example 2. One more chart
#
my $chart2 = $workbook->add_chart( type => 'column', embedded => 1 );
# Configure the chart. # change the categories if required change the values as required
$chart2->add_series(
categories => '=Sheet1!$A$4:$A$7',
values => '=Sheet1!$B$4:$B$7',
);
$worksheet->insert_chart( 'N1', $chart2, 3, 3 );
另外,
如果你不介意xlsx xlsx,你可以使用 Excel :: Writer :: XLSX 。它更积极地维护。
答案 1 :(得分:0)
能够同时解析和使用WriteExcel模块内部功能的技巧是使用use Spreadsheet :: ParseExcel :: SaveParser ;模块。
下面我有一个例子。该示例将不使用图表函数,但您遇到的问题不在于如何使用WriteExcel模块的图表函数,而在于如何解析现有的excel文件,然后将解析后的信息与WriteExcel模块一起使用(最初只考虑新的Excel文件)。
if ( ( -f $excel_file_name ) && ( ( stat $excel_file_name )[7] > 0 ) ) {
#PARSE EXCEL
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::SaveParser;
# Open the template with SaveParser
my $parser = new Spreadsheet::ParseExcel::SaveParser;
my $template = $parser->Parse("$excel_file_name");
my $sheet = 0;
my $row = 0;
my $col = 0;
if ( !defined $template ) {
die $parser->error(), " Perlline:", __LINE__, " \n "; #probably the file is already open by your GUI
}
# Get the format from specific cell
my $format = $template->{Worksheet}[$sheet]->{Cells}[$row][$col]->{FormatNo};
# Add a new worksheet
#for my $worksheet ( $template->worksheets() ) {
my $worksheet_parser = $template->worksheet("$metrict_data_worksheet_name");
my ( $row_min, $row_max ) = $worksheet_parser->row_range();
my ( $col_min, $col_max ) = $worksheet_parser->col_range();
my @row_array_value;
for my $row ( 1 .. $row_max ) { #avoid header start from 1
for my $col ( $col_min .. $col_max ) {
my $cell = $worksheet_parser->get_cell( $row, $col );
next unless $cell;
#print "Row, Col = ($row, $col)\n";
#print "Value = ", $cell->value(), "\n";
#print "Unformatted = ", $cell->unformatted(), "\n";
#print "\n";
push( @row_array_value, $cell->value() );
} #end header column loops for one regression
} #end row loop all lines
#}
# The SaveParser SaveAs() method returns a reference to a
# Spreadsheet::WriteExcel object. If you wish you can then
# use this to access any of the methods that aren't
# available from the SaveParser object. If you don't need
# to do this just use SaveAs().
#
my $workbook;
{
# SaveAs generates a lot of harmless warnings about unset
# Worksheet properties. You can ignore them if you wish.
local $^W = 0;
# Rewrite the file or save as a new file
my $check_if_possible2write = Spreadsheet::WriteExcel->new($excel_file_name);
if ( defined $check_if_possible2write ) { #if not possible it will be undef
$workbook = $template->SaveAs("$excel_file_name");#IMPORTANT this is of type WriteExcel and not ParseExcel
}
else {
print "Not possible to write the Excel file :$excel_file_name, another user may have the file open. Aborting... ", __LINE__, " \n ";
exit;
}
}
#####################FROM HERE YOU CAN USE AGAIN use Spreadsheet::WriteExcel; ####################
use Spreadsheet::WriteExcel;
my $worksheet = $workbook->sheets("$metrict_data_worksheet_name");
my $column_header_count = 0;
foreach my $name ( sort { lc $a cmp lc $b } keys %merged_all_metrics ) {
$worksheet->write( $row_max + 1, $column_header_count, "$merged_all_metrics{$name}" ); #row,col start
$column_header_count++;
}
$worksheet->set_column( 'A:L', 50, undef, 0, 1, 0 ); #grouping #comp_src group
$worksheet->set_column( 'N:R', 50, undef, 0, 1, 0 ); #grouping
$workbook->close() or die "Error closing file: $!"; #CLOSE
}
代码的重要部分是在注释行之后发生的事情:
#####################FROM HERE YOU CAN USE AGAIN use Spreadsheet::WriteExcel; ####################
在那之后,您将看到您有一个$ workbook处理程序。此变量具有所有已解析的信息,更重要的是它来自WriteExcel Object类型,因此您将使用此模块的所有方法。
重要通知。解析器无法解析图表和公式(仅用于解析值),因此您将不得不在每个parse-> write循环中再次编写。