【问题标题】:How can I modify an existing Excel workbook with Perl?如何使用 Perl 修改现有的 Excel 工作簿?
【发布时间】:2014-04-06 12:56:17
【问题描述】:

使用Spreadsheet::WriteExcel,我可以创建一个新工作簿,但如果我想打开现有的工作簿并修改某些列怎么办?我将如何做到这一点?

我可以使用Spreadsheet::ParseExcel 解析工作表中的所有数据,然后使用Spreadsheet::WriteExcel 在某些行/列中将新值写回。有没有一个模块已经将两者结合起来了?

主要是我只想打开一个.xls,覆盖某些行/列,然后保存。

【问题讨论】:

    标签: perl spreadsheet xls


    【解决方案1】:

    Spreadsheet::ParseExcel 将读取现有的 excel 文件:

    my $parser   = Spreadsheet::ParseExcel->new();
    # $workbook is a Spreadsheet::ParseExcel::Workbook object
    my $workbook = $parser->Parse('Book1.xls');
    

    但您真正想要的是Spreadsheet::ParseExcel::SaveParser,它是Spreadsheet::ParseExcelSpreadsheet::WriteExcel 的组合。在文档底部附近有一个example

    【讨论】:

    • 我没有看到任何使用 ParseExcel 写入 excel 书籍的方法
    • Spreadsheet::ParseExcel::SaveParser 会这样做。你打败了我的编辑。 :)
    【解决方案2】:

    如果您安装了 Excel,那么使用 Win32::OLE 执行此操作几乎是微不足道的。这是Win32::OLE自己的文档中的示例:

    use Win32::OLE;
    
    # use existing instance if Excel is already running
    eval {$ex = Win32::OLE->GetActiveObject('Excel.Application')};
    die "Excel not installed" if $@;
    unless (defined $ex) {
        $ex = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;})
                or die "Oops, cannot start Excel";
    }
    
    # get a new workbook
    $book = $ex->Workbooks->Add;
    
    # write to a particular cell
    $sheet = $book->Worksheets(1);
    $sheet->Cells(1,1)->{Value} = "foo";
    
    # write a 2 rows by 3 columns range
    $sheet->Range("A8:C9")->{Value} = [[ undef, 'Xyzzy', 'Plugh' ],
                                       [ 42,    'Perl',  3.1415  ]];
    
    # print "XyzzyPerl"
    $array = $sheet->Range("A8:C9")->{Value};
    for (@$array) {
        for (@$_) {
            print defined($_) ? "$_|" : "<undef>|";
        }
        print "\n";
    }
    
    # save and exit
    $book->SaveAs( 'test.xls' );
    undef $book;
    undef $ex;
    

    基本上,Win32::OLE 为您提供了可用于 VBA 或 Visual Basic 应用程序的所有内容,其中包括各种各样的内容——从 Excel 和 Word 自动化到通过 Windows Script Host 枚举和安装网络驱动器的所有内容。它已成为 ActivePerl 最新版本的标准配置。

    【讨论】:

    • 此外,您可以一次将整个数组写入列\行,这会影响写入速度。如果这还不够,您还可以写入包含宏的 Excel 并使用该模块运行。
    • 谢谢。我注意到 Spreadsheet::ParseXLSX::SaveParser 不存在,所以这对我来说效果更好。
    • @usr-bin-drinking: 很高兴有帮助 :)
    【解决方案3】:

    Spreadsheet::WriteExcel 文档中有一部分涵盖了Modifying and Rewriting Spreadsheets

    Excel 文件是二进制文件中的二进制文件。它包含多个相互关联的校验和,即使更改一个字节也可能导致其损坏。

    因此,您不能简单地附加或更新 Excel 文件。实现这一点的唯一方法是将整个文件读入内存,进行所需的更改或添加,然后再次将文件写出。

    您可以使用 Spreadsheet::ParseExcel::SaveParser 模块读取和重写 Excel 文件,该模块是 Spreadsheet::ParseExcel 和 Spreadsheet::WriteExcel 的包装器。它是Spreadsheet::ParseExcel 包的一部分。

    还有一个例子。

    【讨论】:

      【解决方案4】:

      Spreadsheet::ParseExcel::SaveParser 模块是 Spreadsheet::ParseExcel 和 Spreadsheet::WriteExcel 的包装器。

      我最近更新了文档,希望是 is a clearer example of how to do this

      【讨论】:

      • 我还是不太明白这个例子。我找不到 SaveAs 接受的文档。是否可以传递文件句柄或标量引用而不是文件名?
      • 糟糕,我意识到 John McNamara 在包中包含了一个 write_to_scalar.pl 文件。使用它,我能够对 XLS 文件进行内存修改:-D
      猜你喜欢
      • 1970-01-01
      • 2016-03-14
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 2018-08-31
      • 2017-10-26
      • 2017-11-09
      • 1970-01-01
      相关资源
      最近更新 更多