Как изменить существующую книгу Excel с помощью Perl?

С помощью Spreadsheet::WriteExcel я могу создать новую книгу, но что, если я хочу открыть существующую книгу и изменить определенные столбцы? Как бы я это сделал?

Я мог бы проанализировать все данные из листа, используя Spreadsheet::ParseExcel, а затем записать их обратно с помощью однако новые значения в определенных строках/столбцах с использованием Spreadsheet::WriteExcel. Есть ли модуль, который уже сочетает в себе эти два?

В основном я просто хочу открыть .xls, перезаписать определенные строки/столбцы и сохранить их.


person user105033    schedule 02.09.2009    source источник


Ответы (4)


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::ParseExcel и Таблица::WriteExcel. В нижней части документации есть пример.

person Ether    schedule 02.09.2009
comment
Я не вижу способа писать в книгу Excel, используя ParseExcel - person user105033; 02.09.2009
comment
Spreadsheet::ParseExcel::SaveParser сделает это. ты победил мою правку. :) - person Ether; 02.09.2009

Если у вас установлен 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.

person j_random_hacker    schedule 03.09.2009
comment
Более того, вы можете сразу записывать целые массивы в столбцы\строки, что влияет на скорость записи. Если этого недостаточно, вы также можете написать в Excel макрос и запустить его с этим модулем. - person Vitali Pom; 13.06.2013
comment
Спасибо. Я заметил, что Spreadsheet::ParseXLSX::SaveParser не существует, поэтому для меня это работает намного лучше. - person usr-bin-drinking; 18.12.2014
comment
@usr-bin-drinking: Рад, что был полезен :) - person j_random_hacker; 18.12.2014

В документации Spreadsheet::WriteExcel есть раздел, который охватывает изменение и перезапись электронных таблиц.

Файл Excel представляет собой двоичный файл внутри двоичного файла. Он содержит несколько взаимосвязанных контрольных сумм, и изменение даже одного байта может привести к его повреждению.

Таким образом, вы не можете просто добавить или обновить файл Excel. Единственный способ добиться этого — прочитать весь файл в память, внести необходимые изменения или дополнения, а затем снова записать файл.

Вы можете читать и перезаписывать файл Excel с помощью модуля Spreadsheet::ParseExcel::SaveParser, который является оболочкой для Spreadsheet::ParseExcel и Spreadsheet::WriteExcel. Он является частью пакета Spreadsheet::ParseExcel.

Есть и пример.

person wes    schedule 02.09.2009

Модуль Spreadsheet::ParseExcel::SaveParser представляет собой оболочку Spreadsheet:: ParseExcel и Электронная таблица::WriteExcel.

Недавно я обновил документацию, и, надеюсь, является более наглядным примером того, как сделать это.

person jmcnamara    schedule 02.09.2009
comment
Я все еще не совсем понимаю этот пример. Я не могу найти документацию о том, что принимает SaveAs. Можно ли передавать дескрипторы файлов или скалярную ссылку вместо имени файла? - person Myforwik; 19.04.2012
comment
К сожалению, я понял, что Джон Макнамара включил в пакет файл write_to_scalar.pl. Используя его, я смог сделать модификацию памяти для памяти файла XLS :-D - person Myforwik; 19.04.2012