zoukankan      html  css  js  c++  java
  • 使用perl读取Excel

    使用perl读取Excel

    环境


    • windows 7
    • ActiveState Perl
    • Win32::OLE[perl package]

    基本功能


    • 循环处理多个sheet
    • 读取Excel单元,提取interface信息
    • 格式化标准输出
    • 格式化写入文件

    解析结果



    Perl代码


    #!/usr/bin/perl -w
    
    use strict;
    use Win32::OLE qw(in with);
    use Win32::OLE::Const 'Microsoft Excel';
    
    #################################################
    # Main-routine
    #################################################
    $Win32::OLE::Warn = 3;                                # die on errors...
    
    my $modulename ="";
    my $Sheet ="";
    my $Book  ="";
    
    my @inports;
    my @outports;
    my @vgports;
    
    my $excelvalue=""; 
    
    my $Has_Help = ""; 
    my $work = ""; 
    
    if( $#ARGV < 0 ) {
      &print_usage;
      exit;
    }
    my $filename ="";
    &parse_argv;
    
    if( $Has_Help =~ /TRUE/ )  #显示帮助说明
        {
          &print_usage;
          exit;
        }
    
    if($work =~ /TRUE/ )       #读取表格生成verilog接口文件
       {
          chomp($filename);
          
          # get already active Excel application or open new
          my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
              || Win32::OLE->new('Excel.Application', 'Quit');  
          
          # open Excel file
          $Book = $Excel->Workbooks->Open("$filename"); 
          
          # You can dynamically obtain the number of worksheets, rows, and columns
          # through the Excel OLE interface.  Excel's Visual Basic Editor has more
          # information on the Excel OLE interface.  Here we just use the first
          # worksheet, rows 1 through 4 and columns 1 through 3.
          
          # select worksheet number 1 (you can also select a worksheet by name)
          #for(my $sheetnum=1; $sheetnum < 3;$sheetnum++) #手动设置sheet数量,循环处理每个sheet
          for(my $sheetnum=2; $sheetnum < 12 ;$sheetnum++) #手动设置sheet数量,循环处理每个sheet
          {
              $Sheet = $Book->Worksheets($sheetnum);
    
              &write_result;                             #写入文件
          }
          for(my $sheetnum=2; $sheetnum < 12;$sheetnum++)  #手动设置sheet数量,循环处理每个sheet
          {
              $Sheet = $Book->Worksheets($sheetnum);     #手动设置sheet数量
    
    	  &output_result;                            #Windows终端显示结果
          }
    
          # clean up after ourselves
          $Book->Close;
          print "
    Parse Complete!
    ";
    
          exit;
       }
    else
        {
          &print_usage;
          exit;
        }
    
    
    #################################################
    # Sub-routine: print_usage()   帮助说明
    #################################################
    sub print_usage {
      print "
    Usage: excel2verilog.pl [-option] <excel_file> \
    ";  
      print "                [-w <excel_file>] \
    ";
      print "                [-h] 
    
    ";
      print "For example:
    ";
      print "    perl excel2verilog.pl -w C:/Users/D/Desktop/test.xls
    "; 
      print "    perl excel2verilog.pl -h 
    "; 
      print "
    ";
      print "    Please modify the quantity of sheets(see line 59 and line 65)
    "; 
      print "
    ";
    }
    
    #################################################
    # Sub-routine : parse_argv()   参数读入
    #################################################
    sub parse_argv {
      my $all_arg = "-h|-w";
    
      for(my $i=0; $i<=$#ARGV; $i++) {
        if( $ARGV[$i] =~ /-w/ ) {
          $i++;
          if(!defined $ARGV[$i])
          {
             $Has_Help = "TRUE";
          }
          $work = "TRUE";
          $filename = $ARGV[$i];
        }
        elsif( $ARGV[$i] =~ /-h/ ) {
          $Has_Help = "TRUE";
        }
        else { ### other options
          $Has_Help = "TRUE";
        }
      }
    }
    
    #################################################
    # Sub-routine : get io         得到excel表格中的有用参数存入数组中
    #################################################
    sub get_io{
        @inports  =();   #使用全局变量,分析一个sheet需要清空数组
        @outports =();
        @vgports  =();
        $modulename ="";
        
        my $ipnamerow; 
        my $ipnamecol; 
        my $pinnamerow; 
        my $pinnamecol; 
        my $endrow; 
    
        foreach my $row (1..100)     #将端口数据存入数组,注意扫描范围
        {
            foreach my $col (1..5)  #处理1-5行得到“IP name”/“Pin name”/“Size”的位置
            {
               # skip empty cells
               next unless defined $Sheet->Cells($row,$col)->{'Value'};
        
               # get position 
               $excelvalue = $Sheet->Cells($row,$col)->{'Value'};	 
               if($excelvalue =~ /ip name/i)
               {
                 $ipnamerow = $row; 
                 $ipnamecol = $col; 
                 $modulename = $Sheet->Cells($ipnamerow,($ipnamecol+1))->{'Value'};
    	     #printf("%s,%s
    ",$ipnamerow,$ipnamecol);
               }  
               if($excelvalue =~ /pin name/i)
               {
                 $pinnamerow = $row; 
                 $pinnamecol = $col; 
    	     #printf("%s
    ",$pinnamerow);
               }  
               if($excelvalue =~ /size/i)
               {
                 $endrow = $row - 1; 
    	     #printf("%s
    ",$endrow);
               } 
            }
        }
        foreach my $row (($pinnamerow + 1)..$endrow)  #端口处理,存入数组
        {
            next unless defined $Sheet->Cells($row,$pinnamecol)->{'Value'};
        
            foreach my $col ($pinnamecol)
            {
                # skip empty cells
                next unless defined $Sheet->Cells($row,$col)->{'Value'};
                if(($Sheet->Cells($row,$col)->{'Value'}) eq "IN")
                {
                   next;  # skip "IN" cells
                }
    	    
    	    if(($Sheet->Cells($row,$col)->{'Value'}) eq "OUT")
                {
                   next;    # skip "OUT" cells
                }
    
    	    $_ = $Sheet->Cells($row,$col+1)->{'Value'};
                if(/P|G|I/O/)                 #inout
                {
                   push(@vgports,$Sheet->Cells($row,$col)->{'Value'});
                }
                elsif(/O/D|O/A/)     #output
                {
                   push(@outports,$Sheet->Cells($row,$col)->{'Value'});
                }
                elsif(/I/A|I/D/)     #input 
                {
                   push(@inports,$Sheet->Cells($row,$col)->{'Value'});
                }
            }
        }
    }
    
    #################################################
    # Sub-routine : output_result   格式化输出verilog代码
    #################################################
    sub output_result{
        &get_io; #得到表格中的数据
    
        printf("module  %s(
    ",$modulename);
        foreach my $vgport (@vgports)
        {
            $_ = $vgport;	  
            if(/(.*)<(d*):/i)
            {
               printf("inout     [%2d:0]   %s,
    ",$2,$1);
            }	  
            else
            {
               printf("inout              %s,
    ",$vgport);
            }
        }
        print "
    ";
    
        foreach my $inport (@inports)
        {
            $_ = $inport;	  
            if(/(.*)<(d*):/i)
            {
               printf("input     [%2d:0]   %s,
    ",$2,$1);
            }
            else
            {
               printf("input              %s,
    ",$inport);
            }
        }
        print "
    ";
    
        my $n = @outports;
        my $i =0;
        foreach my $outport (@outports)
        {
            $_ = $outport;	  
            if(/(.*)<(d*):/i)
            {
               printf("output    [%2d:0]   %s",$2,$1);
            }	  
            else
            {
               printf("output             %s",$outport);
            }
            $i++;
            if($i < $n)
            {
               print(",");
            }   
            print("
    ");
        }
        
        print ");
    ";
        print "
    
    
    ";
        print "endmodule
    ";
        print "
    
    
    ";
    }
    
    #################################################
    # Sub-routine : write_result    格式化写入verilog 代码
    #################################################
    sub write_result{
        &get_io;
    
        unlink "$modulename.v";
        open(MODULE, ">> $modulename.v") || die ("Could not open file tempA.txt! 
    ");
        printf MODULE ("module  %s(
    ",$modulename);
        foreach my $vgport (@vgports)
        {
            $_ = $vgport;	  
            if(/(.*)<(d*):/i)
            {
               printf MODULE ("inout     [%2d:0]   %s,
    ",$2,$1);
            }	  
            else
            {
               printf MODULE ("inout              %s,
    ",$vgport);
            }
        }
        print MODULE "
    ";
    
        foreach my $inport (@inports)
        {
            $_ = $inport;	  
            if(/(.*)<(d*):/i)
            {
               printf MODULE ("input     [%2d:0]   %s,
    ",$2,$1);
            }
            else
            {
               printf MODULE ("input              %s,
    ",$inport);
            }
        }
        print MODULE "
    ";
    
        my $n = @outports;
        my $i =0;
        foreach my $outport (@outports)
        {
            $_ = $outport;	  
            if(/(.*)<(d*):/i)
            {
               printf MODULE ("output    [%2d:0]   %s",$2,$1);
            }	  
            else
            {
               printf MODULE ("output             %s",$outport);
            }
            $i++;
            if($i < $n)
            {
               print MODULE (",");
            }   
            print MODULE ("
    ");
        }
        
        print MODULE  ");
    ";
        print MODULE  "
    
    
    ";
        print MODULE  "endmodule
    ";
    
        close MODULE
    }
    

    参考资料


    功能丰富的 Perl: 用 Perl 读写 Excel 文件

  • 相关阅读:
    React 不暴露webpack配置的情况下,修改webpack配置
    Array的一些方法
    ES 6 学习
    位运算解决“一个数组中,只有一个数字出现n次,其他数字出现k次”问题
    句子反转——牛客刷题(java)
    数串——牛客刷题
    链表分割——牛客剑指offer
    合并两个排序链表——牛客offer
    复杂链表的复制——牛客offer
    两个链表的第一个公共结点——牛客offer
  • 原文地址:https://www.cnblogs.com/OneFri/p/6735252.html
Copyright © 2011-2022 走看看