2013-12-16 8 views
2

Я недавний пользователь Perl. Мне нужна помощь в чтении и записи файлов в perl.чтение и запись файла excel в perl

Позвольте мне объяснить сценарий: например, у меня есть файл input.xls, который содержит строковый, числовой, выпадающий список. Некоторые ячейки в листах заблокированы.

Я хочу прочитать данные из файла input.xls и записать его в новый файл с именем output.xls.

Проблема, с которой я столкнулся, заключается в том, что я не могу сохранить форматирование файла, из которого я читаю.

I. Выходной файл, который сгенерирован, не отображает выпадающее меню, а ячейки, заблокированные в файле input.xls, не отображаются в файле output.xls.

Во-вторых, даже форматирование входного файла нарушено в выходном файле. Например, если ячейки объединены во входном файле, форматирование не будет одинаковым в выходном файле. Незлое руководство.

Вот мой код для справки:

#!/usr/bin/perl -w 

use strict; 
use Spreadsheet::ParseExcel; 
use Spreadsheet::WriteExcel; 
use Spreadsheet::ParseExcel::SaveParser; 
use CGI; 
use CGI::Carp qw(fatalsToBrowser); 
print qq[Content-type:text/html \n\n]; 
my $cs='Book2.xls'; 
# Open the template with SaveParser 
my $parser = new Spreadsheet::ParseExcel::SaveParser; 
#my $formatter=Spreadsheet::ParseExcel::FmtJapan->new(); 
my $template = $parser->Parse('e.xls'); 

my $sheet = 0; 
my $row  = 0; 
my $col  = 2; 

# Get the format from the cell 
my $format = $template->{Worksheet}[$sheet] 
         ->{Cells}[$row][$col] 
         ->{FormatNo}; 



# Write data to some cells 
$template->AddCell(0, $row, $col, 1,  $format); 
$template->AddCell(0, $row+1, $col, "This is a hello world eg", $format); 
#$format->{Lock}; 
# Add a new worksheet 
# $template->AddWorksheet('New Data'); 

# The SaveParser SaveAs() method returns a reference to a 
# Spreadsheet::WriteExcel object. If you wish you can then 
# use this to access any of the methods that aren't 
# available from the SaveParser object. If you don't need 
# to do this just use SaveAs(). 
# 
my $workbook; 

{ 
    # SaveAs generates a lot of harmless warnings about unset 
    # Worksheet properties. You can ignore them if you wish. 
    local $^W = 0; 

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

} 

# Use Spreadsheet::WriteExcel methods 

my $worksheet = $workbook->sheets(0); 
# $worksheet->protect(); 
#$worksheet->write('A1:B1','=1+2'); 
#my $locked = $workbook->add_format(); 
# $locked->set_locked(1); # A non-op 

#my $unlocked = $workbook->add_format(); 
#$locked->set_locked(0); 

# Enable worksheet protection 
#$worksheet->protect(); 

# This cell cannot be edited. 
#$worksheet->write('A1:B1', '=1+2', $locked); 

$worksheet->write($row+2, $col, "World2"); 

$workbook->close(); 
print qq[ 
<head> 
<script> 

</script> 
</head> 
<body> 

<p>The download should start shortly. If it doesn't, click 
<a id="downloadLink" href="http://128.9.45.168/~mint/MINT_Portal/macro    /963/cgi/$cs"  download="$cs" target="_blank">here</a>.</p> 
</body> 
</html> 

]; 

ответ

0

Это будет чрезвычайно трудно сохранить форматирование ячеек (для произвольной таблицы). Электронная таблица :: ParseExcel на самом деле не понимает большую часть форматирования (в основном игнорирует ее).

Вы можете обнаружить, что все это работает для конкретной электронной таблицы, но тогда вы найдете таблицу с более сложным форматированием, которая также не работает.

Что вам нужно, это то, что без потерь взаимодействует с объектной моделью документа Excel (DOM). (т. е. загрузить существующую электронную таблицу, клонировать некоторые строки, изменять значения данных, удалять некоторые другие строки, сохранять в другой файл).

Единственный код, который я нашел, что это действительно Apache POI.

К сожалению, это Java API. Я закончил тем, что написал кучу сантехнического кода (на Java), встроенного в мой скрипт perl, используя Inline::Java. (Есть и .NET API, которые тоже могут это сделать, но я был в Linux, и я никогда не мог получить стек Mono + Wine для запуска большей части средств автоматизации Office).

Этот подход работает, но код для его снятия очень сложный. Я бы не поощрял попытки :-)

Есть ли способ избежать этого в perl? (Или только эта часть?)

Смежные вопросы