【问题标题】:Transferring table styles using OpenOffice::OODoc使用 OpenOffice::OODoc 传输表格样式
【发布时间】:2011-10-04 00:40:18
【问题描述】:

我正在尝试将表格的格式从一个 OpenOffice Writer 文件复制到另一个文件...我可以看出我正在将样式名称写入第二个文档,而不是样式数据。

我怀疑这与odfContainer'styles' 部分有关,但我不清楚如何将其写入第二个文档,特别是因为当我检查$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 方法实际将基础数据写入新文档。

编辑:

解压 OpenOffice 文件,我得到几个 xml 文件:

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

等等

OdfContainer'styles''content' 部分对应于styles.xml 和content.xml。 Styles.xml 有点像一个 css 文件,其中包含 ODF 文件的各种标题级别的样式信息。 Content.xml 还包含样式信息,很像 html 文档中的 css 标头。

这里是从odt文件中提取的content.xml的样式部分(其实很像……我没有保存原件)。

<?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 中的单元格样式。

【问题讨论】:

  • 我不是 perl 用户,但我在 PHP 和 C++ 中做过类似的事情。它实际上是这样的:获取文档,打开样式和内容,用新数据替换数据文档的单元格值,将整个包包装到一个新包中......完成。如果您也想更改样式,它只会变得更加复杂。我个人将奇怪的重新设计归咎于 XML,但我也知道 XML 是逻辑,而不是简单的。无论如何...希望我给了你一个提示。您需要自己进行编码。

标签: perl openoffice.org openoffice-writer


【解决方案1】:

您进行了原始导入。该文档说“请记住,在保存之前导入实际上不是由 OODoc::File 执行的,因此导入的数据不会立即可用。”我建议你尝试$container2-&gt;save;,然后在导入样式后立即重新加载,然后在下次保存后查看 Table.A1 是否出现在 doc2.odt 的 content.xml 中:

# 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;

【讨论】:

  • 嗯。这是一个非常有趣的方法。样式信息实际上在 content.xml 中(命名样式和默认样式保存在 styles.xml 中,“自动”样式属于 content.xml)。话虽如此,我会试一试,看看会发生什么......
  • 我在调试器中检查了$newtable,并没有看到原始表格中存在的样式信息。我认为这是我要解决的问题的症结所在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 2017-05-16
  • 1970-01-01
  • 2015-08-09
相关资源
最近更新 更多