2014-02-13 105 views
3

我是一名Perl初學者,曾嘗試過使用Perl來了解它的使用方式和工作原理!我有關於arays,哈希和相關主題的基本知識。我必須爲一個話題開發一個腳本,我很不確定如何去做。我非常需要幫助,非常感謝任何能解釋'如何做'部分的人!在Perl中使用Win32 :: OLE生成Excel輸出

我有一個代碼,其中有3個部分,對於3種不同的組件,我們可以做同樣的事情。基本思想是,它從excel文件中獲取所有標記爲'A'的組件,遍歷excel文件,將相應的RAM和ROM值相加,並打印出沒有重複條目的輸出。第二部分和第三部分是相同的,但部件'B'和'C'。到目前爲止,我能夠在文本文件中輸出所有3個部分的輸出。但是現在我想把所有三個輸出作爲3個單獨的工作表放在Excel工作簿中!

我不是特別確定如何去做。任何想法真的很受歡迎!

PS:請原諒我,如果我沒有在論壇中輸入代碼!這是我的第一篇文章!!

這裏是我的代碼看起來是迄今:

# This Test script was created to try out the possible methods to extract all the Names from the 
# excel report without duplicate entries and find their corresponding RAM/ROM size sum 

# -excel D:\Abc\Test.xlsx -out D:\Abc\Output 

sub usage($) 
{ 
    return shift(@_) . <<"END_USAGE"; 
    Usage: $0 -excel    Specify the file path. 
       -out outputdirectory Specify output directiory    
END_USAGE 
} 

use Getopt::Long; 
use Win32::OLE; 
use List::Util qw(sum); 
use Data::Dumper qw(Dumper); 

my $output_path =(); 
my $excel_path =(); 
my $no_rows =(); 
my $lastCol =(); 

GetOptions("excel=s" => \$excel_path, 
       "out=s" => \$output_path, 
      "h|help" => \$help, 
     ); 

#help message 
die usage("") if ($help); 
system(cls); 
print "\n*******************************************************************\n"; 
print "Component Overview \n"; 
print "*******************************************************************\n"; 
print "Please wait, Processing may take couple of minutes... \n"; 

##File handler for the script file. 
$log_path = $output_path."\\log.txt"; 
$output_file_path = $output_path."\\TestExcel.xlsx"; 
open LogFile,">",$log_path or die "Cannot create the log file:$log_path !!!"; 
print LogFile "Start time :".localtime()."\n"; 

# Start Excel and make it visible 
my $xlApp = Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application', 'Quit'); 
$xlApp->{Visible} = 0; 

#Opening the work book 
my $workBook = $xlApp->Workbooks->Open($excel_path); 
#print "X: " . $workBook . " - " . $excel_path . "\n"; 
my $excelSheet = $workBook->Worksheets("Report"); 
$excelSheet->Activate(); 

print "Reading the file...\n"; 
&ReadExcel(); 

print LogFile "Completed time :".localtime()."\n"; 
print "\nCompleted.Please close this window...\n" ; 
print "*******************************************************************\n"; 

# Sub routine to parse the cosipa file 
sub ReadExcel() 
{ 
my $row_index; 
#Findings the number of valid rows 
$no_rows = $excelSheet->UsedRange->Rows->{'Count'}; 
$lastCol = $excelSheet->UsedRange->Columns->{'Count'}; 
$row_index = findRowindex(); 
my @comp_array =(); 

# Name => ResourceType => size 
my $resultData = {}; 

for(my $index=($row_index+1);$index<=$no_rows;$index++) 
         { 
          my $X = $excelSheet->Cells($index,6)->Value(); 
      my $Y = $excelSheet->Cells($index,7)->Value(); 
      my $name = $excelSheet->Cells($index,9)->Value(); 
      my $resourceType = $excelSheet->Cells($index,3)->Value(); 
      my $size = $excelSheet->Cells($index,2)->Value(); 

      #Name Overview        
      my $currNameTypeMap; 

      if (! exists $resultNameData->{ $name })   # ->: arrow operator is used to dereference reference to arrays or hashes. 
       { 
        $resultNameData->{ $name } = {}; 
       } 
      $currNameTypeMap = $resultNameData->{ $name }; 

      $currNameTypeMap->{ $resourceType } += $size;  

      # Y Overview 
      my $currYTypeMap; 

      if (! exists $resultYData->{ $Y })   # ->: arrow operator is used to dereference reference to arrays or hashes. 
       { 
        $resultYData->{ $cluster } = {}; 
       } 
      $currYTypeMap = $resultYData->{ $Y }; 

      $currYTypeMap->{ $resourceType } += $size; 

      # X Overview 
      my $currXTypeMap; 

      if (! exists $resultXData->{ $X })   # ->: arrow operator is used to dereference reference to arrays or hashes. 
       { 
        $resultXData->{ $X } = {}; 
       } 
      $currXTypeMap = $resultXData->{ $X }; 

      $currXTypeMap->{ $resourceType } += $size;  
     } 

    my @uniqNameArr = sort keys %$resultNameData; 

    my @uniqYArr = sort keys %$resultYData; 

    my @uniqXArr = sort keys %$resultXData; 

      for my $currName (@uniqNameArr) 
      { 
       print $currName . "\n". " RAM: " . $resultNameData->{ $currName }-> { "RAM" } . ", ROM: " . $resultNameData->{ $currName }-> { "ROM" } . "\n"; 
       #print Dumper %$resultData; 
      } 

      print "----------------------------------------------------------------------- \n"; 

      for my $currY (@uniqYArr) 
      { 
       print $currY. "\n". " RAM: " . $resultYData->{ $currY }-> { "RAM" } . ", ROM: " . $resultYData->{ $currY }-> { "ROM" } . "\n"; 
      } 

      print "------------------------------------------------------------------------ \n"; 

      for my $currX (@uniqXArr) 
      { 
       print $currX . "\n". " RAM: " . $resultXData->{ $currX }-> { "RAM" } . ", ROM: " . $resultXData->{ $currX }-> { "ROM" } . "\n"; 
      } 

}

#Sub routine to find the starting row index 
sub findRowindex() 
{ 
my $ret =(); 
for(my $index=1;$index<$no_rows;$index++) 
{ 
    if(defined($excelSheet->Cells($index,1))) 
    { 
     my $cel_value = $excelSheet->Cells($index,1)->Value(); 
     if($cel_value =~ m/^Name$/i) 
     { 
      $ret = $index; 
      last; 
     } 
    } 
} 
return $ret; 

}

#Trim function 
sub trim { 
(my $s = $_[0]) =~ s/^\s+|\s+$//g; 
return $s;   

}

回答

2

一種解決方法:你可以使用Excel :: Writer :: XLSX創建Excel文件,它工作正常,相當健壯。以下是如何將標籤分隔文件轉換爲Excel。

閱讀的Excel:電子表格:: XLSX

use Text::Iconv; 
my $converter = Text::Iconv -> new ("utf-8", "windows-1251"); 


use Spreadsheet::XLSX; 
my $excel = Spreadsheet::XLSX -> new ('test.xlsx', $converter); 
foreach my $sheet (@{$excel -> {Worksheet}}) { 
     printf("Sheet: %s\n", $sheet->{Name}); 
     $sheet -> {MaxRow} ||= $sheet -> {MinRow}; 
     foreach my $row ($sheet -> {MinRow} .. $sheet -> {MaxRow}) {  
       $sheet -> {MaxCol} ||= $sheet -> {MinCol};    
       foreach my $col ($sheet -> {MinCol} .. $sheet -> {MaxCol}) {  
         my $cell = $sheet -> {Cells} [$row] [$col]; 
         if ($cell) { 
          printf("(%s , %s) => %s\n", $row, $col, $cell -> {Val}); 
         } 

       } 
     } 
} 

上編寫Excel:Excel中::作家:: XLSX

my $workbook = Excel::Writer::XLSX->new($xls_filename); 
my $worksheet = $workbook->add_worksheet('data'); 
# Create a format for the headings 
my $header_format = $workbook->add_format(); 
$header_format->set_bold(); 
$header_format->set_size(18); 
$header_format->set_color('black'); 
$header_format->set_align('center'); 
my $row=0; 
while (my $line = <$fh>){ 
    chomp($line);  
    my @cols = split(/\t/,$line); 
    for(my $col=0;$col<@cols;$col++){ 
     if ($row == 0){ 
      $worksheet->write_string($row, $col, $cols[$col],$header_format); 
     } else { 
      $worksheet->write_string($row, $col, $cols[$col]); 
     } 
    } 
    $row++; 
} 
close($fh); 

我希望這可以幫助你。

Regards,

+0

嗨,謝謝你的回覆,非常感謝。有一個小問題。我不幸地不能使用Spreadsheet或Excel :: Writer :: XLSX,因爲我被要求使用Win32 :: OLE編寫腳本。其他希望使用OLE庫的人會對此做進一步補充。所以我堅持這一點! – Swatzz

相關問題