Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > Spreadsheet::ParseExcel::SaveParser


Автор: des00 22.9.2008, 19:57
Простой до офигивания пример.
Открываю экселевский файл пишу новый текст в произвольную ячейку, сохраняю под другим именем.

На винде этот код работает без проблем (немного валит в консоль шлака)
Use of uninitialized value in division (/) at C:/usr/site/lib/Spreadsheet/ParseE
xcel/SaveParser.pm line 148.
Use of uninitialized value in division (/) at C:/usr/site/lib/Spreadsheet/ParseE
xcel/SaveParser.pm line 149.
Use of uninitialized value in division (/) at C:/usr/site/lib/Spreadsheet/ParseE
xcel/SaveParser.pm line 150.
Use of uninitialized value in division (/) at C:/usr/site/lib/Spreadsheet/ParseE
xcel/SaveParser.pm line 151.

но с этим я потом разберусь.. главное что файл создает и текст вставляет..
на линухе же нифига.. говорит что типа забыл я модуль определить и пр.. умничает чёто кроче smile

Can't locate object method "Parse" via package "Spreadsheet::ParseExcel::SaveParser::Workbook" (perhaps you forgot to load "Spreadsheet::ParseExcel::SaveParser::Workbook"?) at /tmp/excel.pl line 7.




Код

#!/usr/bin/perl -w

use strict;
use Spreadsheet::ParseExcel::SaveParser;
use Encode qw(decode);

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse('d:/file.xls');

my $oWs = $oBook->{Worksheet}[0];

$oWs->AddCell(9, 2, decode('utf-8', 'New Cell НОВЫЙ ТЕКСТ'));
$oBook->SaveAs('d:/est.xls');



Подскажите, что не так?

Автор: nitr 23.9.2008, 00:05
Это вам поможет:
Код

use Spreadsheet::ParseExcel::SaveParser;
use Spreadsheet::ParseExcel::SaveParser::Workbook;
use Spreadsheet::ParseExcel::SaveParser::Worksheet;


Как бы странно это не звучало smile но модуль реально так себя ведет, есть подозрения на некие кривости в нём ;)
Я думаю многие знают ответ ;)

Автор: des00 23.9.2008, 07:06
Блин))) реально...

я прежде чем задать вопрос попрбовал вот так
Код

use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::SaveParser;
use Spreadsheet::ParseExcel::SaveParser::Workbook;


но потом одумался, ибо бред.. и пошел на форум.. а оставалось лишь одну строку дописать smile

Автор: des00 23.9.2008, 09:05
а как в S:PE объеденить ячейки?

я пытался так..

Код

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse($xls.'docs.xls');
my $oWs = $oBook->{Worksheet}[0];
$oWs->{MergedArea} = [6,0,6,25];

Автор: nitr 23.9.2008, 12:47
des00, ну это уже читать доку ;)
а вот бредом является, то что эти модули используются в SaveParser.pm, но нигде там "не подгружаются" smile

Добавлено через 1 минуту и 8 секунд
А может эта задумка такая? Кто сможет объяснить? smile

Автор: des00 23.9.2008, 12:56
да читал я доку.. день уже читаю)) дока то какаято неподробная.. 

Автор: nitr 23.9.2008, 12:58
des00, дам подсказку - объединение это свойство ячейки/ячеек.

Добавлено через 29 секунд
А потому что проект - alpha

Автор: des00 23.9.2008, 13:13
Код

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse($xls.'docs.xls');
my $oWs = $oBook->{Worksheet}[0];
$oWS->{Cells}[$iR][$iC] ->{Merged} = 1


оно?

А в каком видел задается  [$iR][$iC] ?

Судя по всему это нето.. вот в WriteExcel есть метод merge_range, там все ясно.. а тут нифига блин

дай примерчик,а ? ))

Автор: nitr 23.9.2008, 14:05
des00, я не нашел у него нормального описания методов smile да и сами методы...
Модуль явно не дописан, или они должны документировать методы (ну и написать их)

Вот вам поможет...
Код

sub MergeArea {
    my $oWs = shift;
    my ($sR, $sC, $eR, $eC) = (@_);
    
    for(my $i = $sR-1; $i<=$eR-1; $i++) {
        for(my $j = $sC-1; $j<=$eC-1; $j++) {
            $oWs->{Cells}[$i][$j]->{Merged} = 1 if $oWs->{Cells}[$i][$j];
        }
    }
}

Только доработайте smile

Использовать как
Код

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse($xls.'docs.xls');
my $oWs = $oBook->{Worksheet}[0];
MergeArea($oWs, 6, 1, 6, 25);

Т.е. в Экселе это строка №6 столбец №1 по строку №6 по строку №25.

ну и конечно протестировать стоит smile

Автор: des00 23.9.2008, 17:46
Спасибо, завтра обязательно испытаю..
Ежели пойдет что не так, ждите снова в той же теме в тот же час  smile 

Автор: des00 24.9.2008, 06:44
эксперименты ни к чему не привели :(

Код

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse($xls.'docs.xls');
my $oWs = $oBook->{Worksheet}[0];
MergeArea($oWs, 6, 1, 6, 25);

Undefined subroutine &main::MergeArea 

Код

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse($xls.'docs.xls');
my $oWs = $oBook->{Worksheet}[0];
$oBook->{Worksheet}[0]->MergeArea($oWs, 6, 1, 6, 25);

Can't locate object method "MergeArea" via package "Spreadsheet::ParseExcel::SaveParser::Worksheet"

Код

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse($xls.'docs.xls');
my $oWs = $oBook->{Worksheet}[0];
$oWs->MergeArea($oWs, 6, 1, 6, 25);

Can't locate object method "MergeArea" via package "Spreadsheet::ParseExcel::SaveParser::Worksheet"

Код

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse($xls.'docs.xls');
my $oWs = $oBook->{Worksheet}[0];
$oWs->{Cells}->MergeArea($oWs, 6, 1, 6, 25);

Can't call method "MergeArea" on unblessed reference


p.s. попробовал вариации с MergeArea и MergedArea

Автор: des00 24.9.2008, 07:43
Вот нашел, что модуль оказывается использует какойто древний метод объединения вместо нужного..

http://www.perlmonks.org/index.pl?node_id=666704

Теперь, прошу помощи, как это решение применить к моему случаю.

Автор: shamber 24.9.2008, 10:23
des00, а вы в main добавляли 
Код

my $oBook = Spreadsheet::ParseExcel::SaveParser::Workbook->Parse($xls.'docs.xls');
my $oWs = $oBook->{Worksheet}[0];
MergeArea($oWs, 6, 1, 6, 25);

sub MergeArea {
    my $oWs = shift;
    my ($sR, $sC, $eR, $eC) = (@_);
    
    for(my $i = $sR-1; $i<=$eR-1; $i++) {
        for(my $j = $sC-1; $j<=$eC-1; $j++) {
            $oWs->{Cells}[$i][$j]->{Merged} = 1 if $oWs->{Cells}[$i][$j];
        }
    }
}


Автор: des00 24.9.2008, 11:44
Теперь все добавил, ошибок нет, но и объединения не происходит.

Автор: nitr 24.9.2008, 14:34
des00, тогда приведите (лучше вложите) вывод вот дампа...

Код

...
use Data::Dumper 'Dumper'

...
MergeArea...;
print Dumper($oWs);

запустите примерно так perl script.pl > log.txt. Потом выложите сюда этот log.txt.

У меня всё сработало и нормально объединило. Что вам ещё посоветовать: так это самому написать "обложку" для Spreadsheet::ParseExcel и Spreadsheet::WriteExcel.

P.S.: Лично я бы не использовал модуль Spreadsheet::ParseExcel::SaveParser. Можно взять за основу некоторые его "моменты" для своего модуля.

Автор: des00 24.9.2008, 17:57
Сделал дамп,
т.к. стуктура документа у меня сложная, то и дамп вышел офгенно большой.
Делал по ячейкам 1,2,1,10

Код

MergeArea ($oWs,1,2,1,10);


Такое чувство, что файл сохраняется в формате xls95 (в котором нет объед. ячеек)
Что конкретно смотреть в логах?

http://dump.ru/file/1078646

Также сделал простой файлик в OpenOffice Calc, сохранил в формате XLS 97/2000
и прогнал тот же скрипт, лог поменьше.
http://dump.ru/file/1078644

Может кто поделится 100% верным файлом xls нужной версии, чтобы я попробовал именно на вашем.

По поводу своих обверток и других модулей. Мне надо то 3-5 строк объединить и все. Все остальное меня устраивает и вполне работает. Не хочется городить огороды из-за этого.

Автор: des00 25.9.2008, 07:04
создал в excel 2000 простой файл, сделал в нем средствами экселя объединенную ячейку.
Запустил скрипт
лог http://dump.ru/file/1079738

на выходе в файле все тоже самое что у меня было но нет ни одной объединенной ячейки.. :(
даже той что средствами экселя делал

Вывод: S:PE:SP создает файл xls 5\95 где форматом не предусмотрены объд.ячейки.. иного я не могу подумать

Автор: nitr 25.9.2008, 09:38
des00, тогда почему я смог это сделать?

P.S.: у меня не было времени смотреть логи, позже гляну как освобожусь.

Добавлено через 16 секунд
Цитата(des00 @  25.9.2008,  07:04 Найти цитируемый пост)
Вывод: S:PE:SP создает файл xls 5\95 где форматом не предусмотрены объд.ячейки.. иного я не могу подумать

не в этом проблема.

Автор: des00 25.9.2008, 10:35
Спасибо, жду. Очень хочется побороть этот косяк.

Вот пробный xls-файлик (excel 2000)  http://dump.ru/file/1079892

Автор: nitr 26.9.2008, 12:34
des00, в логах всё нормально (на первый взгляд). В ячейках, которые вы объединяете есть текст?

Автор: des00 26.9.2008, 18:47
изначально, в оригинальном файле, был.. 

но пробуя на пустом документе (что я выложил выше) без текста, все равно ничего не выходит :(

Автор: nitr 3.10.2008, 01:05
des00, я про то, что вы, например, объединяете ячейки 1 2 3, в которых есть (хотя бы в одной) значения. Тогда надо иначе, из первой ячейки запомнить значение, в остальных удалять, затем снова в первую вставить запомн.значение... Но думаю, можно погуглить и есть готовые решения.

Автор: nitr 3.10.2008, 01:21
Код
#/usr/bin/perl    
use strict;
use warnings;

use Spreadsheet::ParseExcel::SaveParser;
use Spreadsheet::ParseExcel::SaveParser::Workbook;
use Spreadsheet::ParseExcel::SaveParser::Worksheet;

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

my $oWs = $oBook->{Worksheet}[0];

MergeArea($oWs, 1, 2, 1, 4);

$oExcel->SaveAs($oBook, 'temp.xls');  # as the same name

sub MergeArea {
    my $oWs = shift;
    my ($sR, $sC, $eR, $eC) = (@_);
    
    my $value = $oWs->{Cells}[$sR-1][$sC-1]->{_Value};
    for(my $i = $sR-1; $i<=$eR-1; $i++) {
    for(my $j = $sC-1; $j<=$eC-1; $j++) {
        $oWs->{Cells}[$i][$j]->{_Value} = '';
        $oWs->{Cells}[$i][$j]->{Val} = '';
        $oWs->{Cells}[$i][$j]->{Merged} = 1 if $oWs->{Cells}[$i][$j];
    }
    }
    $oWs->{Cells}[$sR-1][$sC-1]->{_Value} = $value;
    $oWs->{Cells}[$sR-1][$sC-1]->{Val} = $value;
}

на выходе отличный результат smile (в архиве temp.xls)

Добавлено через 1 минуту и 11 секунд
Лучше в доке прочесть как изменить значение (по правилам модуля этого smile )
        $oWs->{Cells}[$i][$j]->{_Value} = '';
        $oWs->{Cells}[$i][$j]->{Val} = '';

Думаю это не очень "эстетично" smile)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)