package GetExcelData;
use Win32::OLE;   #导入win32 OLE包
use Win32::OLE::Const "Microsoft Excel";
use Cwd;#获取本地路径模块

#数据类型如下所示
#$EXCEL->$sheet->{@rowdata,@coulmndata}
#@rowdata={@row1,@row2,....};
#@rowdata={@coulmndata1,@coulmndata2,....};
#存储行和列的所有数据都是一个三维的数组
push (@INC,'pwd');
#new一个新的对象
sub new
{
 my $class = shift;
 #一个空的引用
 my $ref = {};
 #将引用和对象绑定
 bless($ref,$class);

 #返回引用
 return $ref; 
}

#析构函数
sub DESTROY
{
    my $self = shift @_;
 foreach my $keY (keys %{$self})
 {
  print $keY is destroy;
 }
}

#获得所有EXCEL文件的内容
sub GetAllExcelDate
{
    #获取对象引用
    my $self = shift @_;

 #获取本地路径
 my $dir = getcwd;
 my @FilePathArray; 

 #获取本地路径下的所有文件
 &GetLocalFile($dir,\\\\@FilePathArray);

 #获取路径下的Excel文件
 my @ExcelFilePath = &GetFileExcelFile(@FilePathArray);
 #获取文件夹下Excel的数量
 my $iExcelNum = @ExcelFilePath; 

 #目录下没有EXCEL文件
 if($iExcelNum == 0)
 {
  print "There is no Excel File";
  return 0;
 }

 #遍历所有的Excel文件
 foreach my $ExcelPaht( @ExcelFilePath )
 {

  #Excel文件不存在给出提示
  die "the $ExcelPaht does not  exit\\\\n" unless -e $ExcelPaht;

  #创建一个Excel操作对象
  my $excel =  Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application');  

  #使这个对象可见
  $excel -> {Visible} = 0;
  #打开一个Excel工作簿
  my $workbook = $excel-> Workbooks -> Open("$ExcelPaht");
  # 关掉Excel的提示,比如是否保存之类的。
  $excel->{DisplayAlerts} = 'False'; 

    #获得该Excel文件的所有sheet名字
  my @AllSheetName;

  #获得工作表的数量
  my $sheets_num = $excel->WorkSheets->{'Count'};  
  foreach my $num (1..$sheets_num) 
  {
   my $sheet = $excel->WorkSheets($num);
   push @AllSheetName, $sheet->{'Name'};
  }

  print "*" x 20,".\\\\n";
  print "\\\\nInput Excel File is $ExcelPaht\\\\n";
  print "*" x 20,".\\\\n";
  print "\\\\nSheet is\\\\n";
  print "@AllSheetName\\\\n";
  print "*" x 20,".\\\\n";

        #存储sheet内容的哈希    
     my %SheetContent;
     foreach $SheetName(@AllSheetName)
  {
   #激活要导入数据的sheet
   my $sheet    = $workbook -> Worksheets($SheetName);
   $sheet-> Activate;
   #获取EXCEL激活sheet的行和列数目
   my $row_num = $sheet->{UsedRange}->{Rows}->{Count};
   my $coulmn_num = $sheet->{UsedRange}->{Columns}->{Count}; 

      #获取某个sheet的所有行和列数据
         my @AllSheetContent;

         #获得所有行的数据
   my @AllRowDate;
   #获得该sheet的行数目
   my $i_SheetRowNum = $sheet->{UsedRange}->{Rows}->{Count};
   #遍历每一行
   foreach my $i_RowIndex(1..$i_SheetRowNum) 
   {
    #获取一个sheet每一行的数据
    my @RowArrayTemp; 

    die "The search index $i_RowIndex is bigger than max row num  $row_num" if($i_RowIndex > $row_num);
    #获取这个sheet某一行的数据
    foreach my $coulmnIndex(1..$coulmn_num)
    {

     my $Excelvalue = $sheet->Cells($i_RowIndex,$coulmnIndex)->{'Value'}; 
     push  @RowArrayTemp,$Excelvalue;
    }
    push @AllRowDate,[@RowArrayTemp];
   }


   #获取sheet所有列的数据
   my @AllCoulmnDate;
   my $i_SheetCoulmnNum =  $sheet->{UsedRange}->{Columns}->{Count};
   #遍历所有列
   foreach my $i_CoulmnIndex(1..$i_SheetCoulmnNum) 
   {
    #获取一个sheet每一列的数据
    my @CoulmnArrayTemp; 

    die "The search index $i_CoulmnIndex is bigger than max row num " if($i_CoulmnIndex > $coulmn_num);
    #获取这个sheet某一列的数据
    foreach my $RowIndex(1..$row_num)
    { 
     my $Excelvalue = $sheet->Cells($RowIndex,$i_CoulmnIndex)->{'Value'}; 
     push  @CoulmnArrayTemp,$Excelvalue;
    } 
    push @AllCoulmnDate,[@CoulmnArrayTemp];
   }

   #注意这里二维数据的赋值方式!!!!!!!!!
   push @AllSheetContent,[@AllRowDate];
   push @AllSheetContent,[@AllCoulmnDate];

   #获取该sheet下的所有行和列数据
   #注意这里少了\\\\就成了数组元素的个数了!!!!!
   $SheetContent{$SheetName} = \\\\@AllSheetContent; 
  }
 my $PointEndIndex = rindex($ExcelPaht,"/");
 my $ExcelName = substr($ExcelPaht,$PointEndIndex+1,length($ExcelPaht)-$PointEndIndex-1);
 $self->{$ExcelName} = {%SheetContent};

 #退出EXCEL
 $excel-> Quit;
 }
}


#获取导入的所有EXCEL的名字
sub GetExcelName
{
 my $self = shift;
 #返回所有的EXCEL键值
 return keys %{$self};
}


#获得EXCEL的所有sheet的名字
sub GetExcelSheetName
{
 my $self = shift;
 my $s_ExcelName = shift;

 #判断要查找的EXCEL是否导入 
 unless(exists $self->{$s_ExcelName}) 
 {
  die "\\\\nThe Excel $s_ExcelName does not exit\\\\n";
 }

 #得到EXcel对应的sheet哈希
 my $hashSheet = $self->{$s_ExcelName};

 return keys %{$hashSheet};
}


#获取某个Excel某个Sheet一行的数据
sub GetExcelSheetRowDate
{
 #获取对象引用
 my($self,$s_ExcelName,$s_SheetName,$i_RowNum) = @_; 
 $i_RowNum--;
 #得到获取的行数据
 my @RowContent;
 #判断要查找的EXCEL是否导入 
 unless(exists $self->{$s_ExcelName}) 
 {
  die "\\\\nThe Excel $s_ExcelName does not exit\\\\n";
 }

 #得到EXcel对应的sheet哈希
 my $hashSheet = $self->{$s_ExcelName};

 #判断要获取的sheet是否存在
 unless(exists $hashSheet->{$s_SheetName}) 
 {
  die "\\\\nThe Excel Sheet $s_SheetName does not exit\\\\n";
 }

 #获取所有行和列数据的数组
 my @ArrayTest = @{$self->{$s_ExcelName}->{$s_SheetName}};

 #获取这个sheet有多少行,行数据存在第一位
 my $i_size = @{$ArrayTest[0]};

 #判断获取的行号是否在行范围内 
 unless($i_RowNum <= $i_size -1)
<= $i_size -1)
<= $i_size -1)
<= $i_size -1)
<= $i_size -1)
<= $i_size -1)
 {
  die "\\\\n the row index  $i_RowNum is bigger than row num $i_size\\\\n";
 }

 #三维数据解引用得到获取的行元素
 @RowContent = @{${$ArrayTest[0]}[$i_RowNum]};
  #返回得到的行数据
 @RowContent; 
}


#获取某个Excel某个Sheet一列的数据
sub GetExcelSheetCoulmnDate
{
 #获取对象引用
 my($self,$s_ExcelName,$s_SheetName,$i_ColNum) = @_; 
 $i_ColNum--;
 #得到获取的行数据
 my @ColContent;
 #判断要查找的EXCEL是否导入 
 unless(exists $self->{$s_ExcelName}) 
 {
  die "\\\\nThe Excel $s_ExcelName does not exit\\\\n";
 }

 #得到EXcel对应的sheet哈希
 my $hashSheet = $self->{$s_ExcelName};

 #判断要获取的sheet是否存在
 unless(exists $hashSheet->{$s_SheetName}) 
 {
  die "\\\\nThe Excel Sheet $s_SheetName does not exit\\\\n";
 }

 #获取所有行和列数据的数组
 my @ArrayTest = @{$self->{$s_ExcelName}->{$s_SheetName}};

 #获取这个sheet有多少列,列数据存在第二位
 my $i_size = @{$ArrayTest[1]};

 #判断获取的行号是否在行范围内 
 unless($i_ColNum <= $i_size -1)
<= $i_size -1)
<= $i_size -1)
<= $i_size -1)
<= $i_size -1)
<= $i_size -1)
 {
  die "\\\\n the row index  $i_ColNum is bigger than row num $i_size\\\\n";
 }

 #三维数据解引用得到获取的行元素
 @ColContent = @{${$ArrayTest[1]}[$i_ColNum]};
  #返回得到的行数据
 @ColContent; 

#获取Excel某个sheet的行的数目
sub GetExcelSheetRowNum
{
 #获取对象引用
 my($self,$s_ExcelName,$s_SheetName) = @_;
 #判断要查找的EXCEL是否导入 
 unless(exists $self->{$s_ExcelName}) 
 {
  die "\\\\nThe Excel $s_ExcelName does not exit\\\\n";
 }

 #得到EXcel对应的sheet哈希
 my $hashSheet = $self->{$s_ExcelName};

 #判断要获取的sheet是否存在
 unless(exists $hashSheet->{$s_SheetName}) 
 {
  die "\\\\nThe Excel Sheet $s_SheetName does not exit\\\\n";
 }

 #获取所有行和列数据的数组
 my @ArrayTest = @{$self->{$s_ExcelName}->{$s_SheetName}};
 #获取这个sheet有多少行,行数据存在第一位
 my $i_Rowsize = @{$ArrayTest[0]};

 $i_Rowsize;


#获取Excel某个sheet的列的数目
sub GetExcelSheetColNum
{
 #获取对象引用
 my($self,$s_ExcelName,$s_SheetName) = @_;
 #判断要查找的EXCEL是否导入 
 unless(exists $self->{$s_ExcelName}) 
 {
  die "\\\\nThe Excel $s_ExcelName does not exit\\\\n";
 }

 #得到EXcel对应的sheet哈希
 my $hashSheet = $self->{$s_ExcelName};

 #判断要获取的sheet是否存在
 unless(exists $hashSheet->{$s_SheetName}) 
 {
  die "\\\\nThe Excel Sheet $s_SheetName does not exit\\\\n";
 }

 #获取所有行和列数据的数组
 my @ArrayTest = @{$self->{$s_ExcelName}->{$s_SheetName}};
 #获取这个sheet有多少行,行数据存在第一位
 my $i_Colsize = @{$ArrayTest[1]};

 $i_Colsize;


#获取本地路径下的所有文件,(注意这个是使用指针递归得到路径)
sub GetLocalFile
{
 my $dir = shift;
 my $FilePath = shift;
 #递归得到文件路径
    opendir DH, $dir;
    foreach my $file (readdir DH)
 {
        next if $file eq "." or $file eq "..";
        $file = "$dir/$file";
        if(-d $file)
  {
            &GetLocalFile($file,\\\\@$FilePath);
        }
        else
  {
   push @$FilePath,$file;      
        }
 }

 return 1;
}


#获得目录下的所有EXCEL文件
sub GetFileExcelFile
{
 my @FilePathArray = @_;
 my @ExcelFilePath;


 foreach my $FilePath(@FilePathArray)
 {
     #文件不可读写也不存在的话过滤掉
  unless(-r -w -e $FilePath)
  { 
   next;
  }

  $FilePath =~ s/\\\\\\\\/\\\\//g; 

  #获得文件结束符
  my $PointEndIndex = rindex($FilePath,".");
  my $EndName = substr($FilePath,$PointEndIndex+1,length($FilePath)-$PointEndIndex-1);

  #是Excel的结束符号
  if($EndName =~ /xls|xlsx/i)
  {
   push @ExcelFilePath,$FilePath; 
  }
 }

 @ExcelFilePath;

#模块结束必须返回1
1;

 

 

 

package WriteExcelData;
use Win32::OLE;   #导入win32 OLE包
use Win32::OLE::Const "Microsoft Excel";

#向Excel写入数据

#new一个对象出来
sub new
{
 my $class = shift;
 my $FilePath = shift @_;

 #Excel文件不存在给出提示
 die "the $ExcelPaht does not  exit\\\\n" unless -e $FilePath;
 #一个空的引用
 #my $ref = {};
 $excel =  Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application');  
 #使这个对象可见
 $excel -> {Visible} = 0;

 #打开一个Excel工作簿
 $work = $excel-> Workbooks -> Open("$FilePath");
 my $ref ={};
 # 关掉Excel的提示,比如是否保存之类的。
 $excel->{DisplayAlerts} = 'False'; 

 bless($ref,$class);
 #返回引用
 return $ref; 
}

#向Excel某个sheet写入一行数据
sub WriteRowDate
{
 #对象自引用,行列起始位
 my $ref = shift;
 my $SheetName = shift;
 my $RowBegin = shift;
 my $CoulmnBegin = shift;
 my @RowConten = @_;

 #激活要导入数据的sheet
 my $sheet    = $work -> Worksheets($SheetName);
 $sheet-> Activate;

 foreach $CellContent(@RowConten)
 {
  $sheet->Cells($RowBegin, $CoulmnBegin)->{'Value'} = $CellContent;
  $CoulmnBegin++;
 }
 $excel->Save;
 1;
}

#向Excel某个sheet写入一列数据
sub WriteColDate
{
 my $ref = shift;
 my $SheetName = shift;
 my $RowBegin = shift;
 my $CoulmnBegin = shift;
 my @ColConten = @_;

 #激活要导入数据的sheet
 my $sheet    = $work -> Worksheets($SheetName);
 $sheet-> Activate;

 foreach $CellContent(@ColConten)
 {
  $sheet->Cells($RowBegin, $CoulmnBegin)->{'Value'} = $CellContent;
  $RowBegin++;
 }
 $excel->Save;
 1;
}

#退出Excel
sub ColseExcel
{
 #退出EXCEL
 $excel-> Quit;
 1;
}

1;

 

 

 

use  GetExcelData;
use WriteExcelData;

#获得二维数组的一维全部元素,第三个变量是得到元素的数组引用。
sub GetArrayValue
{
 my($InputPoint,$iGetindex,$GetPoint) = @_;
 my $count = 0;

 #print "the array is @$InputPoint\\\\n";

 foreach my $index (@$InputPoint)
 {
    # print "\\\\nEach Array value is @$index\\\\n";
  if($iGetindex == $count)
  {
   push @$GetPoint,@$index;
   return 1; 
  }
   $count++;
 }

 0;
}

 #new一个对象的引用
 my $ExcelPoint = GetExcelData->new();
 #获取本地路径下所有EXCEL数据
 $ExcelPoint->GetAllExcelDate();

 #获得导入的所有的Excel的名字
 my @ExcelName;
 @ExcelName = $ExcelPoint->GetExcelName();

 #print "\\\\nExcel Name is @ExcelName\\\\n";

 foreach my $ExcelIndex (@ExcelName)
 {
  my @SheetName = $ExcelPoint->GetExcelSheetName($ExcelIndex);
  print "\\\\nsheet name is @SheetName\\\\n";
  my @SheetRowDate = $ExcelPoint->GetExcelSheetRowDate($ExcelIndex,$SheetName[2],1);
  my @SheetCoulmnDate = $ExcelPoint->GetExcelSheetCoulmnDate($ExcelIndex,$SheetName[0],1);
  my $iRowNum = $ExcelPoint->GetExcelSheetRowNum($ExcelIndex,$SheetName[0]);
  my $iColNum = $ExcelPoint->GetExcelSheetColNum($ExcelIndex,$SheetName[0]);
  print "\\\\nsheet Row Date is @SheetRowDate\\\\n";
  print "\\\\nsheet Coulmn Date is @SheetCoulmnDate\\\\n";
  print "\\\\n行$iRowNum\\\\n";
  print "\\\\n列$iColNum\\\\n";
 }