修改 .xlsx 文件(Excel 2007 及更高版本)

8

我用 Spreadsheet::ParseExcel::SaveParser 成功解析了一个 xls 文件,并使用 Spreadsheet::WriteExcel 进行了修改。

然而,处理 xlsx 文件则完全不同。 我正试图找出如何使用 Spreadsheet::XLSX 进行解析,并使其与 Excel::Writer::XLSX 兼容。 Spreadsheet::ParseExcel::SaveParser 有一个 SaveAs() 方法,可以将其应用于解析的 xml 文件上,以便使用 Spreadsheet::WriteExcel 方法,但我不知道如何使它适用于 xlsx 文件。

编辑: 当使用 Spreadsheet::ParseExcel::SaveParserSpreadsheet::WriteExcel 时,我可以编写:

#!/usr/bin/perl -w

use strict;
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::SaveParser;

# Open the template with SaveParser
my $parser   = new Spreadsheet::ParseExcel::SaveParser;
my $template = $parser->Parse('template.xls');

# Rewrite the file or save as a new file
$workbook = $template->SaveAs('new.xls');

# Use Spreadsheet::WriteExcel methods
my $worksheet  = $workbook->sheets(0);
$worksheet->write($row+2, $col, "World2");

$workbook->close();

我希望能够使用xlsx文件进行相同的操作。因此,我尝试使用Spreadsheet::XLSXExcel::Writer::XLSX。 而不是

my $parser   = new Spreadsheet::ParseExcel::SaveParser;
my $template = $parser->Parse('template.xls');

我使用。
my $excel = Spreadsheet::XLSX -> new ('test.xlsx');

现在,在解析 xlsx 文件之后,我想向其中添加一些数据,但不知道如何操作。 如上所述,当使用 Spreadsheet::ParseExcel::SaveParser 时,我使用了 SaveAs() 函数, 但是 Spreadsheet::XLSX 没有 SaveAs() 方法。那么我该如何向已解析的 xlsx 文件中添加数据呢?

我在 link 中没能找到答案。

谢谢您的帮助 :)


你的意思是什么:“如何使其工作”?这里有一个示例程序:http://search.cpan.org/~dmow/Spreadsheet-XLSX-0.13-withoutworldwriteables/lib/Spreadsheet/XLSX.pm。具体哪里出了问题?我们喜欢这里有代码示例的具体问题。 - user4035
我已经编辑并添加了代码示例。希望我的问题现在更清晰了,有人可以帮忙...谢谢 :) - MiSo
请注意,根据 CPAN 上的描述部分Spreadsheet::WriteExcel 处于“维护模式”,建议使用 Excel::Writer::XLSX 进行替换。 - zb226
3个回答

2

Spreadsheet::XLSX模块是一个解析器,即它不仅可以读取文件,而且还可以理解文件内容,但不能写入文件。

如果要将文件写回磁盘,请使用John McNamara的卓越(没有双关语:))Excel::Writer::XLSX

http://search.cpan.org/~jmcnamara/Excel-Writer-XLSX/lib/Excel/Writer/XLSX.pm

基本上,您可以通过Spreadsheet::XLSX将XLSX文件读入多级哈希引用中,其结构如下:

$xlsx_as_read->{worksheet_name}->{column}->{row}=value;

修改您发布的CPAN链接上的示例:

修改您发布的CPAN链接上的示例:

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

# Text::Iconv is not really required.
# This can be any object with the convert method. Or nothing.

use Spreadsheet::XLSX;
my $xlsx_as_read;

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) {
                           $xlsx_as_read->{$sheet->{Name}}->{$col}->{$row}=$cell -> {Val};
                       }
               } 
       }
}

然后将它倒回一个Excel::Writer::XLSX工作簿中,可以写入磁盘。
my $new_workbook = Excel::Writer::XLSX->new( 'output_file_name.xlsx' );
#populate cells with a loop similar to the one before, 
#iterating on $xlsx_as_read

0
my $excel_xlsx = Spreadsheet::XLSX -> new ('input_x.xlsx');
my ($sheet_xlsx, $row, $col, $cell);

请立即在xls文件中编写内容:

my $excel_xls = Spreadsheet::WriteExcel->new('input.xls');
my $sheet_xls = $excel_xls->add_worksheet();

获取内容:

for $sheet_xlsx ( @{ $excel_xlsx->{Worksheet} } )
{
    for $row ( $sheet_xlsx->{MinRow} .. $sheet_xlsx->{MaxRow} )
    {
        for $col ( $sheet_xlsx->{MinCol} .. $sheet_xlsx->{MaxCol} )
        {
            my $cell = $sheet_xlsx->{Cells}[$row][$col];
            if($cell->{Val})
            {
            }

在xls文件中写入此处:

            $sheet_xls->write($row, $col, $cell->{Val});
        }
    }
}

0
尝试这个:-
使用 Spreadsheet::XLSX; my $excel = Spreadsheet::XLSX -> new ('test.xlsx', $converter);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接