使用Perl Win32 :: OLE从Excel工作表获取超链接列表

时间:2012-05-25 14:44:57

标签: perl excel hyperlink ole

我想在Excel电子表格中更改一堆超链接的路径。在搜索Google之后,我遇到了solutions 添加超链接到电子表格的问题,但没有更改它们。微软展示了如何使用VBA here

由于我想编辑文档中的每个超链接,因此我不知道如何解决的关键步骤是:

  1. 获取Perl中的超链接对象列表

  2. 逐一提取地址

  3. 运行正则表达式以进行路径更改

  4. 将更新的路径存储在Hyperlink->对象中并重复

  5. 我是使用OLE的新手,我被绊倒了(1)。这是我到目前为止所尝试的:

    #!perl
    use strict;
    use warnings;
    use 5.014;
    use OLE;
    use Win32::OLE::Const "Microsoft Excel";
    
    my $file_name = 'C:\path\to\spreadsheet.xlsx';
    my $excel = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;});
    $excel->{Visible} = 1;
    my $workbook = $excel->Workbooks->Open($file_name);
    my $sheet = $workbook->Worksheets('Sheet 1');
    foreach my $link (in $sheet->Hyperlinks ) {
    say $link->Address;
    }
    

    但这会给代码带来错误:

      

    Win32 :: OLE(0.1709):GetOleEnumObject()不是C:/Dwimperl/perl/vendor/lib/Win32/OLE/Lite.pm第167行的Win32 :: OLE :: Enum对象。   如果没有包或对象引用,则无法在script.pl第14行调用方法“超链接”。

    它正在选择正确的工作表,所以我不确定为什么它抱怨对象引用。我尝试了几种变体(在超链接周围添加{},删除'in',尝试将其存储为列表,作为哈希,以及作为哈希的引用)任何人都可以给我一些指示吗?谢谢!

1 个答案:

答案 0 :(得分:2)

首先,您应该设置$Win32::OLE::Warn=3,这样一旦出现问题,您的脚本就会出现问题。其次,我知道你不能在旧版本的Excel中按名称选择工作表,尽管我不知道最新版本中的内容是什么。最后,我认为您会发现使用Win32::OLE::Enum更容易。

以下是一个例子:

#!/usr/bin/env perl

use 5.014;
use warnings; use strict;

use Carp qw( croak );
use Path::Class;
use Try::Tiny;
use Win32::OLE;
use Win32::OLE::Const 'Microsoft Excel';
use Win32::OLE::Enum;
$Win32::OLE::Warn = 3;

my $book_file = file($ENV{TEMP}, 'test.xls');
say $book_file;

my $excel = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;});
$excel->{Visible} = 1;

my $book = $excel->Workbooks->Open("$book_file");
my $sheet = get_sheet($book, 'Sheet with Hyperlinks');
my $links = $sheet->Hyperlinks;
my $it = Win32::OLE::Enum->new($links);

while (defined(my $link = $it->Next)) {
    my $address = $link->{Address};
    say $address;
    if ($address =~ s/example/not.example/) {
        $link->{Address} = $address;
        $link->{TextToDisplay} = "Changed to $address";
    }
}

$book->Save;
$book->Close;
$excel->Quit;

sub get_sheet {
    my ($book, $wanted_sheet) = @_;

    my $sheets = $book->Worksheets;
    my $it = Win32::OLE::Enum->new($sheets);

    while (defined(my $sheet = $it->Next)) {
        my $name = $sheet->{Name};
        say $name;
        if ($name eq $wanted_sheet) {
            return $sheet;
        }
    }

    croak "Could not find '$wanted_sheet'";
}

工作簿确实包含名为"Sheet with Hyperlinks"的工作表。该表格中的单元格A1包含http://example.comA2包含http://stackoverflow.com