Передача стилей таблицы с использованием OpenOffice :: OODoc - PullRequest
35 голосов
/ 13 июля 2011

Я пытаюсь скопировать форматирование таблицы из одного файла OpenOffice Writer в другой ... Я могу сказать, что пишу имя стиля во второй документ, но не данные стиля.

Я подозреваю, что это как-то связано с 'styles' частью odfContainer, но я не понимаю, как записать это во второй документ, особенно потому, что когда я проверяю объект $style в отладчик, похоже, идентичен объекту $doc, который предположительно загрузил часть 'content'.

Вот что у меня так далеко ...

#! /usr/bin/perl

use warnings;
use strict;

use OpenOffice::OODoc;

my $file='mytest.odt';
my $outfile='doc2.odt';

# load input file
my $container = odfContainer("$file");
$container->raw_export("styles.xml");
my $doc = odfDocument
        (
        container => $container,
        part      => 'content'
        );

my $style = odfDocument
        (
        container => $container,
        part      => 'styles'
        );

# load output file
my $container2 = odfContainer( $outfile, create => 'text' );
$container2->raw_import("styles.xml");

my $doc2 = odfDocument
        (
        container => $container2,
        part      => 'content'
        );


# Load table from 'mytest.odt'
my $table=$doc->getTable(0);

# Get style from first cell in $table
my $headerstyle=$doc->getStyle( $doc->getCell($table, 0, 0) );

# Create table in $doc2
my $newtable=$doc2->appendTable('newtable', 1, 1, 'table-style' => $doc->getStyle($table) );

# Set style of first cell in $newtable to 'Table1.A1'
$doc2->cellStyle( $newtable, 0, 0, 'Table1.A1' );

# Write 'doc2.odt' to disk
$container2->save;

Причина, по которой я загружаю 'Table1.A1' в качестве стиля ячейки, заключается в том, что я обнаружил следующее глубоко внутри $table при проверке внутри отладчика:

'next_sibling' => OpenOffice::OODoc::Element=HASH(0x102029250)
   'att' => HASH(0x102029180)      
      'style:family' => 'table-cell'  
      'style:name' => 'Table1.A1'     
   'empty' => 0                    
   'first_child' => OpenOffice::OODoc::Element=HASH(0x1020294a0)
      'att' => HASH(0x102029200)      
         'fo:background-color' => '#cccccc'
         'fo:border' => '0.0069in solid #000000'
         'fo:padding-bottom' => '0in'    
         'fo:padding-left' => '0.075in'  
         'fo:padding-right' => '0.075in' 
         'fo:padding-top' => '0in'       
         'style:vertical-align' => 'top' 
         'style:writing-mode' => 'lr-tb' 

Я знаю, что атрибуты соответствуют тому, что я пытаюсь скопировать, и я также знаю из экспериментов, что метод 'getStyle' возвращает атрибут style::name ... Я просто не знаю, как получить от установки Атрибут style::name, использующий метод cellStyle, фактически записывает базовые данные в новый документ.

Edit:

Распаковывая файл OpenOffice, я получаю несколько XML-файлов:

  • settings.xml
  • styles.xml
  • content.xml

и т.д.

Части 'styles' и 'content' OdfContainer соответствуют styles.xml и content.xml. Styles.xml немного похож на файл CSS, содержащий информацию о стиле для различных уровней заголовка файла ODF. Content.xml также содержит информацию о стиле, очень похожую на заголовок css в HTML-документе.

Вот часть стиля файла content.xml, извлеченного из файла odt (на самом деле он мне очень нравится ... Я не сохранил оригинал).

<?xml version="1.0" encoding="utf-8"?>
<office:document-content>
   ...
   <office:automatic-styles>
    <style:style style:name="Table6" style:family="table" style:master-page-name="First_20_Page">
      <style:table-properties style:width="6.9208in" style:page-number="auto" table:align="left" style:writing-mode="lr-tb" />
    </style:style>
    <style:style style:name="Table6.A" style:family="table-column">
      <style:table-column-properties style:column-width="1.2729in" />
    </style:style>
    <style:style style:name="Table6.B" style:family="table-column">
      <style:table-column-properties style:column-width="3.2604in" />
    </style:style>
    <style:style style:name="Table6.C" style:family="table-column">
      <style:table-column-properties style:column-width="2.3875in" />
    </style:style>
    <style:style style:name="Table6.1" style:family="table-row">
      <style:table-row-properties style:min-row-height="0.1597in" style:keep-together="true" fo:keep-together="auto" />
    </style:style>
    <style:style style:name="Table6.A1" style:family="table-cell">
      <style:table-cell-properties 
         style:vertical-align="bottom" 
         fo:background-color="#cccccc" 
         fo:padding-left="0.075in" 
         fo:padding-right="0.075in" 
         fo:padding-top="0in" 
         fo:padding-bottom="0in" 
         fo:border-left="0.0069in solid #000000" 
         fo:border-right="none" 
         fo:border-top="0.0069in solid #000000" 
         fo:border-bottom="0.0069in solid #000000" 
         style:writing-mode="lr-tb">
        <style:background-image />
      </style:table-cell-properties>
    </style:style>
 ...
  • style: name = "Table6" описывает стиль для текущей таблицы,
  • style: name = "Table6.A" описывает стиль для столбца A этой таблицы,
  • style: name = "Table6.A1" описывает стиль для ячейки A1

Выполнение необработанного экспорта раздела «content.xml» входного файла, а затем необработанного импорта в выходной файл делает перенос данных из одного файла в другой.

#! /usr/local/bin/perl

use warnings;
use strict;

use OpenOffice::OODoc;

my $infile=$ARGV[0];
my $outfile='outfile.odt';

my $incontainer = odfContainer( $infile );
$incontainer->raw_export("content.xml");

my $outcontainer = odfContainer( $outfile, create => 'text' );
$outcontainer->raw_import("content.xml");

$outcontainer->save;

Запуск oodoc.pl infile.odt, затем разархивирование outfile.odt и проверка содержимого content.xml показывает, что стиль был успешно передан:

<style:style style:name="Table1" style:family="table">
  <style:table-properties style:width="6.925in" table:align="margins" />
</style:style>
<style:style style:name="Table1.A" style:family="table-column">
  <style:table-column-properties 
   style:column-width="2.3083in" 
   style:rel-column-width="21845*" />
</style:style>
<style:style style:name="Table1.A1" style:family="table-cell">
  <style:table-cell-properties 
      fo:background-color="#cccccc" 
      fo:padding="0.0382in" 
      fo:border-left="0.0007in solid #000000" 
      fo:border-right="none" 
      fo:border-top="0.0007in solid #000000" 
      fo:border-bottom="0.0007in solid #000000">
    <style:background-image />
  </style:table-cell-properties>
</style:style>

Теперь, когда это было сделано, мне нужно загрузить и использовать стили ячеек в $outcontainer.

1 Ответ

1 голос
/ 06 августа 2012

Вы сделали необработанный импорт.Документы для этого гласят: «Помните также, что импорт на самом деле не выполняется OODoc :: File до сохранения, и поэтому импортированные данные не сразу доступны».Я предлагаю вам попробовать $container2->save;, а затем заново загрузить его сразу после импорта стилей, а затем посмотреть, будет ли Table.A1 отображаться в файле content.xml файла doc2.odt после следующего сохранения:

# load output file

my $container2 = odfContainer( $outfile, create => 'text' );
$container2->raw_import("styles.xml");

# Carry out the import and reload it with the new styles.
$container2->save;

$container2 = odfContainer( $outfile );

my $doc2 = odfDocument
        (
        container => $container2,
        part      => 'content'
        );


# Load table from 'mytest.odt'
my $table=$doc->getTable(0);

# Get style from first cell in $table
my $headerstyle=$doc->getStyle( $doc->getCell($table, 0, 0) );

# Create table in $doc2
my $newtable=$doc2->appendTable('newtable', 1, 1, 'table-style' => $doc->getStyle($table) );

# Set style of first cell in $newtable to 'Table1.A1'
$doc2->cellStyle( $newtable, 0, 0, 'Table1.A1' );

# Write 'doc2.odt' to disk
$container2->save;
...