Script works fine, but ftp code uploading the xls but uploading with 0 byte, but if ftp code present in before of the following snippet, FTP Works Fine,
What is the error in code,
my $workbook = Spreadsheet::WriteExcel->new('TestRPT.xls');
my $worksheet = $workbook->add_worksheet('TestRPT Report');
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use Spreadsheet::WriteExcel;
use POSIX qw(strftime);
my $CurTimeStamp=time;
my $LastSunTimestamp=($CurTimeStamp - 168*60*60);
my $row;
my $PinNumber;
my $PinAmount;
my $get_date;
my $get_time;
my $get_time_stamp;
my $DoFTPFlg = "yes";
# Create a new workbook and add a worksheet.
my $workbook = Spreadsheet::WriteExcel->new('TestRPT.xls');
my $worksheet = $workbook->add_worksheet('TestRPT Report');
# Write some text. in write function First Argument for ROW, Second Argument for COLUMN, Third Argument for Title/Text to display
$worksheet->write(0, 0, 'val1');
$worksheet->write(0, 1, 'val2');
$worksheet->write(0, 2, 'val3');
$worksheet->write(0, 3, 'val4');
my $cnt = 1;
$get_time_stamp = time;
$get_date = strftime("%m/%d/%y",localtime($get_time_stamp));
$get_time = strftime("%H:%M",localtime($get_time_stamp));
# Write some numbers.
$worksheet->write($cnt, 0, "val1");
$worksheet->write($cnt, 1, "val2");
$worksheet->write($cnt, 2, "val3");
$worksheet->write($cnt, 3, "val4");
if ($DoFTPFlg eq "yes") {
print "DO FTP";
use Net::FTP;
my $ftp;
$ftp = Net::FTP->new("mysite.in", Debug => 0);
$ftp->login("user",'pass');
$ftp->cwd("/www/");
$ftp->put("TestRPT.xls");
$ftp->quit;
}
You should close your $workbook object before trying to do anything with the file.
From the documentation:
An explicit close() is required if the file must be closed prior to performing some external action on it such as copying it, reading its size or attaching it to an email.
Try a slight modification on your code. Instead of
$ftp->put("TestRPT.xls");
Create another file in the www directory and try to ftp that file. If that file is called test.txt, change your line to:
$ftp->put("TestRPT.xls");
Thus, the only change in your code is the name of the file being FTP'd. If your FTP works, the problem isn't with the FTP, but with the Spreadsheet::WriteExcel module. As Mat has already stated, you need to do an explicit close on your object.
If your FTP doesn't work, it probably is an issue with the FTP call (although it looks fine to me).
Related
Below is the Perl code in .pm file which is supposed to replace the specified strings (that are in "quotes") with some values. But its not happening. Can anyone explain what is happening in this code?
package SomePackage;
require Exporter;
#ISA = qw(Exporter);
#EXPORT = qw(send_request, create_mmd_and_transfer, update_mmd_file);
sub send_request {
my ( $service, $action, $torole ) = #_;
my ( $seller_request_mmd );
my $replace_contents = ();
$replace_contents{"REPLACE_Service"} = $service;
$replace_contents{"REPLACE_RequestAction"} = $action;
$replace_contents{"REPLACE_TradingPartner"} = $torole;
$replace_contents{"REPLACE_Requestxml"} = "Request.xml";
create_mmd_and_transfer( \%replace_contents, $seller_request_mmd, "/MMD.xml" );
}
sub create_mmd_and_transfer {
my $local_replace_contents = shift;
my $input_mmd = shift;
my $local_output_mmd = shift;
my $output_mmd = shift;
update_mmd_file( "$input_mmd", "temp_mmd_file.xml", $local_replace_contents );
}
sub update_mmd_file {
my $input_file = shift;
my $output_file = shift;
my $contents = shift;
open( MMD_FILE, "<$input_file" )
or main::error_exit(" Cannot open MMD file template $input_file \n $input_file not found int the Templates folder \n Please place the same and then run the script ");
open( TEMP_MMD_FILE, ">$output_file" );
while ( <MMD_FILE> ) {
s/^M//g; # Getrid of the ^Ms
foreach my $content ( keys( %$contents ) ) {
my $exact_value = ${%$contents}{$content};
if ( $main::test_scenario =~ /^Invalid Request Action \a\n\d Service/
and ( $content =~ /REPLACE_Service|REPLACE_RequestAction/i ) ) {
}
else {
if ( $exact_value ne "" ) {
s/$content/$exact_value/g;
}
}
}
print TEMP_MMD_FILE;
}
close MMD_FILE;
close TEMP_MMD_FILE;
}
The following will not make your script work, just create the better base for some future questions.
Before you even thinking about posting a perl question here:
1.) add to the top of your script:
use strict;
use warnings;
Posting a code here without these two lines, nobody will bother even trying to read the code.
2.) use perl -c SomePackage.pm for the check. If it will tell you: SomePackage.pm syntax OK - you can start thinking about posting a question here. ;)
Some basic problems with your script:
package SomePackage;
use strict; # see the above
use warnings;
require Exporter;
# these variables are defined outside of this package, so, tell perl this fact. use the `our`
our #ISA = qw(Exporter);
#the use warnings will warn you about the following line
# #EXPORT = qw(send_request, create_mmd_and_transfer, update_mmd_file);
#the correct one is without commas
our #EXPORT = qw(send_request create_mmd_and_transfer update_mmd_file); #not saying anything about the #EXPORT rudeness. :)
#my $replace_contents = ();
#the $replace_contents is a scalar. Bellow you using a hash. So,
my %replace_contents;
#or use the scalar but the lines bellow should use the hashref notation, e.g.
# $replace_contents->{"REPLACE_Service"} = $service;
# you decide. :)
# the seller_request_mmd contains undef here.
create_mmd_and_transfer( \%replace_contents, $seller_request_mmd, "/MMD.xml");
# also bellow, in the subroutine definition it wants 4 arguments.
# indicates a problem...
# using 2-arg open is not the best practice.
# Also, you should to use lexical filehandles
# open (MMD_FILE, "<$input_file")
# better
open (my $mmd_file, '<', $input_file)
# of course, you need change every MMD_FILE to $mmd_file
# check the result of the open and die if not successful
# or you can use the
use autodie;
# instead of $exact_value = ${%$contents}{$content};
# you probably want
my $exact_value = $contents->{$content};
Indent your code!
All the above are just about the syntactic problems and not solving anything about the "logic" of your code.
Ps: And me is still an beginner, so, others sure will find much more problems with the above code.
Ok. Here's what I've done to test this.
Firstly, you didn't give us an input file or the code that you use to call the module. So I invented them. I made the simplest possible input file:
REPLACE_Service
REPLACE_RequestAction
REPLACE_TradingPartner
REPLACE_Requestxml
And this driver program:
#!/usr/bin/perl
use strict;
use warnings;
use SomePackage;
send_request('foo', 'bar', 'baz');
sub error_exit {
die #_;
}
The first time, I ran it, I got this error:
Undefined subroutine &main::send_request called at test line 8.
That was because your #EXPORT line was wrong. You had:
#EXPORT = qw(send_request, create_mmd_and_transfer, update_mmd_file);
But the point of qw(...) is that you don't need the commas. So I corrected it to:
#EXPORT = qw(send_request create_mmd_and_transfer update_mmd_file);
Then I re-ran the program and got this error:
Cannot open MMD file template
not found int the Templates folder
Please place the same and then run the script at test line 11.
That looked like there was something missing. I changed the error message, adding indicators of where the variable interpolation was supposed to happen:
open( MMD_FILE, "<$input_file" )
or main::error_exit(" Cannot open MMD file template <$input_file> \n <$input_file> not found int the Templates folder \n Please place the same and then run the script ");
Then the error message looked like this:
Cannot open MMD file template <>
<> not found int the Templates folder
Please place the same and then run the script at test line 11.
So it seems clear that the $input_file variable isn't set in the update_mmd_file() subroutine. Tracing that variable back, we see that this value is originally the $seller_request_mmd variable in send_request(). But in send_request() you declare $seller_request_mmd but you never give it a value. So let's do that:
my ( $seller_request_mmd ) = 'test_input.txt';
Now, when I run your program, it runs to completion without any errors. And I find a new temp_mmd_file.xml is generated. But it is exactly the same as the input file. So more investigation is needed.
Digging into the update_mmd_file() subroutine, we find this interesting line:
my $exact_value = ${%$contents}{$content};
I think you're trying to extract a value from $contents, which is a hash reference. But your syntax is wrong. You were probably aiming at:
my $exact_value = ${$contents}{$content};
But most Perl programmers prefer the arrow notation for working with reference look-ups.
my $exact_value = $contents->{$content};
Making that change and re-running the program, I get an output file that contains:
foo
bar
baz
Request.xml
Which is exactly what I expected. So the program now works.
But there is still a lot of work to do. As you have been told repeatedly, you should always add:
use strict;
use warnings;
to your code. That will find a lot of potential problems in your code - which you should fix.
To be honest, this feels to me like you were trying to run before you could walk. I'd recommend spending some time to work through a good Perl introductory book before taking on my more Perl work.
And there was a lot of useful information missing from your question. It wouldn't have taken as long to get to the solution if you had shown us your driver program and your input data.
I am trying to read a file and store it into a hash. When i print out the contents of the hash only the first line from the file stores.
#!/usr/local/bin/perl
use strict;
use warnings;
use Data::Dump;
local $/ = "";
my %parameters;
open(my $PARAMS, 'SimParams.conf')
or die "Unable to open file, $!";
while(<$PARAMS>) {
my #temp = split(/:\s*|\n/);
$parameters{$temp[0]} = $temp[1];
}
dd(\%parameters);
exit 0
The dd(\%parameters) shows only the first line of the file as key and value. How can I get all 3 lines to be Key and Value pairings in this hash?
EDIT: SimParams file as requested:
RamSize: 1000
PageSize: 200, 200
SysClock: 1
The datadump gives the output:
{ RamSize => "1000\r" }
The line
local $/ = "";
is reading your 3 line file as 1 chunk, the entire file. If you eliminate that code, your hash should be created.
You should probably chomp your input to remove the newline . Place it in your code before splitting to #temp.
chomp;
Borodin best explains what local $/ = ""; does.
Setting $/ to the null string enables paragraph mode. Each time you read from $PARAMS (which should be $params because it is a local variable) you will be given the next block of data until a blank line is encountered
It looks like there are no blank lines in your data, so the read will return the entire contents of the file
You don't say why you modified the value of $/, but it looks like just removing that assignment will get your code working properly
I need to keep the date time format in Excel but it is saving as a plain text in excel.
Please find the code as follows,
use strict;
use warnings;
use Spreadsheet::WriteExcel;
my #array = ("Name","2014-04-01 00:00:00AM","2014-04-01 22:00:00AM","Value");
my $filename = "report.xls";
my $workbook = Spreadsheet::WriteExcel->new($filename);
my $worksheet = $workbook->add_worksheet();
$worksheet->write_row($row++,$col,\#array);
Thanks in advance!
The documentation states:
$worksheet->write_row(0, 0, $array_ref);
# The above example is equivalent to:
$worksheet->write(0, 0, $array[0]);
$worksheet->write(0, 1, $array[1]);
$worksheet->write(0, 2, $array[2]);
If you pass an array ref for batch writing, I guess it's not possible to specify what format to use for each column. However, there are other methods like
write_date_time($row, $col, $date_string, $format)
You would have to write each row cell separately, but you would get the desired format. (I guess)
I am currently working with the core module IO::Uncompress::Unzip to read the content of a zip file in Perl.
I previously used Archive::Zip, which is a great module, and didn't give me that many headaches, but it's not bundled as a core module.
I would like to get the last modified time of the files that were zipped in my zip file.
For example, I have the following file : "test.zip" which contains "1.txt", "2.txt", "3.txt". The zip was, for instance, last modified today, whereas the txt files were modified a week ago.
How can I get the last modified date of each compressed file in my zip ?
I could do this very easily with Archive::Zip, but not with this module..
Here's the code I'm using :
use strict;
use warnings;
use IO::Uncompress::Unzip qw($UnzipError);
my $zipfile = 'test.zip';
my $u = new IO::Uncompress::Unzip $zipfile
or die "Cannot open $zipfile: $UnzipError";
for (my $status = 1; $status > 0; $status = $u->nextStream) {
my $name = $u->getHeaderInfo->{Name};
# my $date = ctime(stat($u)->mtime); -> This doesn't work, even though $u is considered as a filehandle in the IO::Uncompress::Unzip documentation..
warn "Processing member $name\n" ;
while(<$u>) {
print "Line $. -> $_";
}
}
Any ideas or workarounds to solve my problem ?
Thanks !
You can try $u->getHeaderInfo->{Time}
Check all attributes with
use Data::Dumper;
print Dumper scalar $u->getHeaderInfo;
I have a perl script to automate many multiple alignments (I'm making the script first with only one file and one multiple alignment - big one though. I can then modify for multiple files) and I want to output the resulting file, but I am unsure on how to do with with AlignIO: so far I have:
use warnings;
use strict;
use Bio::AlignIO;
use Bio::SeqIO;
use Bio::Tools::Run::Alignment::Clustalw;
my $file = shift or die; # Get filename from command prompt.
my $factory = Bio::Tools::Run::Alignment::Clustalw->new(-matrix => 'BLOSUM');
my $ktuple = 3;
$factory->ktuple($ktuple);
my $inseq = Bio::SeqIO->new(
-file => "<$file",
-format => $format
);
my $seq;
my #seq_array;
while ($seq = $inseq->next_seq) {
push(#seq_array, $seq);
}
# Now we do the actual alignment.
my $seq_array_ref = \#seq_array;
my $aln = $factory->align($seq_array_ref);
Once the alignment is done I have $aln which is the alignment I want to get out of the process as a fasta file - I tried something like:
my $out = Bio::AlignIO->new(-file => ">outputalignmentfile",
-format => 'fasta');
while( my $outaln = $aln->next_aln() ){
$out->write_aln($outaln);
}
but it didn't work, presumably because the method next_aln() only applies to AlignIO things, which $aln is probably not. So I need to know what it is that is generated by the line my $aln = $factory->align($seq_array_ref); and how to get the aligned sequences output into a file. My next step is tree estimation or network analysis.
Thanks,
Ben.
$out->write_aln($outaln);
Was the only line needed to write the object returned by the clustalw line to output the object to that stream.