如何从 Perl 创建或读取 OpenOffice 电子表格?

发布于 2024-07-08 20:01:29 字数 44 浏览 6 评论 0原文

在 Perl 中创建和读取 OpenOffice 电子表格的好方法是什么?

What is a good way to create and read an OpenOffice spreadsheet in Perl?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

千秋岁 2024-07-15 20:01:29

我认为 open Office 本机文档格式基于 OpenDocument 规范,并且基本上是一种 zip 压缩的 XML 格式。 如果确实如此,您可能可以使用您选择的 perl XML 操作工具来操作它。

或者,CPAN 上有 Open Office OpenDocument 连接器模块套件,为 OpenDocument 规范提供高级 API。

据我所知,这些模块中的表方法应该允许在 OO Calc 文档中读取和写入数据。

I think that the open office native document format is based around the OpenDocument specifications, and is bascially a zip compressed XML format. This being true you could probably manipulate it using your perl XML manipulation tools of choice.

Alternatively, there's the Open Office OpenDocument Connector suite of modules on the CPAN which offers a high level API to the OpenDocument spec.

To my knowledge, the table methods in these modules should allow for both reading and writing data in OO Calc documents.

椵侞 2024-07-15 20:01:29

我使用 OpenOffice::OOCBuilder 创建大型颜色编码表。 非常喜欢它。
对于更简单的任务,我经常使用任何电子表格程序都可以轻松打开的纯 CSV 格式。

但是,您可能会选择 Excel 格式以与其他人兼容。

I used OpenOffice::OOCBuilder for creating large color-coded tables. Liked it very much.
For simpler tasks, I often use plain CSV format that is readily opened by any spreadsheet program

However, you might chose the Excel stuff for compatibility with other people.

风向决定发型 2024-07-15 20:01:29

OpenOffice 支持多种格式,如果您正在寻找可以读取/写入与 Excel 兼容的电子表格的格式,请查看 Spreadsheet::ParseExcel 用于阅读,以及 Spreadsheet::WriteExcel 用于写入。 我都用过它们,它们非常成熟并且效果很好。

OpenOffice supports a number of formats, if you are looking for something that can read/write Excel-compatible spreadsheets check out Spreadsheet::ParseExcel for reading, and Spreadsheet::WriteExcel for writing. I have used them both, they are pretty mature and work well.

征﹌骨岁月お 2024-07-15 20:01:29

这是2.4版本的,因为最新版本不稳定。 但有时它确实可以与最新版本一起使用。 这将允许 Calc 中的实时 DDE 功能,而不是操作文件。 这是在 XP 上使用 Cygwin Perl,但应该可以与其他人一起使用。 我只想说 Excel VBA 编程 API 好 10 倍,混乱程度也低 10 倍。 那是相当糟糕的。

[代码]

use Win32::OLE;

Win32::OLE->Option(Warn => 3); # Turn on warnings for easier debugging

#Win32::OLE->GetActiveObject
# Get the currently running process or create a new one
$objServiceManager = Win32::OLE->GetActiveObject("com.sun.star.ServiceManager") || Win32::OLE->new("com.sun.star.ServiceManager") || die "CreateObject: $!"; 

$Stardesktop = $objServiceManager->createInstance("com.sun.star.frame.Desktop");

# $Stardesktop->terminate();exit; # will kill ALL OpenOffice docs!!!
# Doc = StarDesktop.loadComponentFromURL(sURL, "_default", 0, aMediaDesc)

$propValue[0] = $objServiceManager->Bridge_GetStruct("com.sun.star.beans.PropertyValue");
$propValue[0]->{Name} = "Hidden"; # This does not work!
$propValue[0]->{Value} = 1;

#Open the file and update its links if you have DDE links in your file
$propValue[1] = $objServiceManager->Bridge_GetStruct("com.sun.star.beans.PropertyValue");
$propValue[1]->{Name} = "UpdateDocMode";
$propValue[1]->{Value} = 3; # com.sun.star.document.UpdateDocMode.FULL_UPDATE

$calc = $Stardesktop->loadComponentfromUrl("file:///C:/Documents and Settings/Chloe/Desktop/MyFile.ods", "MyCalc", 0, \@propValue );
# load a new blank spreadsheet
$calc = $Stardesktop->loadComponentFromURL( "private:factory/scalc", "_blank", 0, [] );

# How to hide, as loading the document hidden does not work.
$calc->getCurrentController->getFrame->getContainerWindow()->setVisible(0);

$oSheet = $calc->getSheets->getByIndex(0);

# how to execute an UNO command, such as menu items
# http://wiki.services.openoffice.org/wiki/Framework/Article/OpenOffice.org_2.x_Commands
$frame = $calc->getCurrentController->getFrame;
$dispatchHelper = $objServiceManager->createInstance("com.sun.star.frame.DispatchHelper");
$dispatchHelper->executeDispatch(
    $frame, 
    ".uno:CalculateHard",
    #".uno:UpdateAll", 
    #".uno:UpdateAllLinks", 
    #".uno:DataAreaRefresh",
    "_self",
    0,
    []
);


$row = 5;
$cellValue = $oSheet->getCellByPosition(0, $row)->getString(); # get a cell value

# sort in decending order
$range = $oSheet->getCellRangeByName("A1:P$row");
$fields[0] = $objServiceManager->Bridge_GetStruct("com.sun.star.table.TableSortField");
$fields[0]->{Field} = 7; # column number
$fields[0]->{IsAscending} = 0;
$unoWrap = $objServiceManager->Bridge_GetValueObject;
$unoWrap->Set ("[]com.sun.star.table.TableSortField", \@fields);
$sortDx = $range->createSortDescriptor();
$sortDx->[0]->{Name} = "ContainsHeader";
$sortDx->[0]->{Value} = 1;
$sortDx->[3]->{Name} = "SortFields";
$sortDx->[3]->{Value} = $unoWrap;
#$sortDx->[3]->{Value} = \@fields; # You would think this would work? It doesn't.
$range->sort($sortDx);


# create a new sheet to paste to
$calc->getSheets->insertNewByName("NewSheet", 1 );
$sheet2 = $calc->getSheets->getByIndex(1);
$calc->CurrentController->Select($sheet2);

# copy row
$pasteHere = $sheet2->getCellByPosition(0, 0)->CellAddress;
$copyRange = $oSheet->getCellRangeByName("A1:Q1")->RangeAddress;
$oSheet->copyRange($pasteHere, $copyRange);

$cellValue = $sheet2->getCellByPosition(16, $row)->getValue()); # get cell value as integer
$date = $sheet2->getCellByPosition(5, $row)->getString(); # must get dates as strings

$calc->getCurrentController->getFrame->getContainerWindow()->setVisible(1); # set visible
$calc->close(0); # close program window
#print Win32::OLE->LastError, "\n";

[/代码]

This is with version 2.4, because the latest version is unstable. It does work with the latest though sometimes. This will allow realtime DDE features in Calc as opposed to manipulating files. This is using Cygwin Perl on XP but should work with others. I just want to say the Excel VBA programming API is 10 times better and 10 times less confusing. That is pretty bad.

[code]

use Win32::OLE;

Win32::OLE->Option(Warn => 3); # Turn on warnings for easier debugging

#Win32::OLE->GetActiveObject
# Get the currently running process or create a new one
$objServiceManager = Win32::OLE->GetActiveObject("com.sun.star.ServiceManager") || Win32::OLE->new("com.sun.star.ServiceManager") || die "CreateObject: $!"; 

$Stardesktop = $objServiceManager->createInstance("com.sun.star.frame.Desktop");

# $Stardesktop->terminate();exit; # will kill ALL OpenOffice docs!!!
# Doc = StarDesktop.loadComponentFromURL(sURL, "_default", 0, aMediaDesc)

$propValue[0] = $objServiceManager->Bridge_GetStruct("com.sun.star.beans.PropertyValue");
$propValue[0]->{Name} = "Hidden"; # This does not work!
$propValue[0]->{Value} = 1;

#Open the file and update its links if you have DDE links in your file
$propValue[1] = $objServiceManager->Bridge_GetStruct("com.sun.star.beans.PropertyValue");
$propValue[1]->{Name} = "UpdateDocMode";
$propValue[1]->{Value} = 3; # com.sun.star.document.UpdateDocMode.FULL_UPDATE

$calc = $Stardesktop->loadComponentfromUrl("file:///C:/Documents and Settings/Chloe/Desktop/MyFile.ods", "MyCalc", 0, \@propValue );
# load a new blank spreadsheet
$calc = $Stardesktop->loadComponentFromURL( "private:factory/scalc", "_blank", 0, [] );

# How to hide, as loading the document hidden does not work.
$calc->getCurrentController->getFrame->getContainerWindow()->setVisible(0);

$oSheet = $calc->getSheets->getByIndex(0);

# how to execute an UNO command, such as menu items
# http://wiki.services.openoffice.org/wiki/Framework/Article/OpenOffice.org_2.x_Commands
$frame = $calc->getCurrentController->getFrame;
$dispatchHelper = $objServiceManager->createInstance("com.sun.star.frame.DispatchHelper");
$dispatchHelper->executeDispatch(
    $frame, 
    ".uno:CalculateHard",
    #".uno:UpdateAll", 
    #".uno:UpdateAllLinks", 
    #".uno:DataAreaRefresh",
    "_self",
    0,
    []
);


$row = 5;
$cellValue = $oSheet->getCellByPosition(0, $row)->getString(); # get a cell value

# sort in decending order
$range = $oSheet->getCellRangeByName("A1:P$row");
$fields[0] = $objServiceManager->Bridge_GetStruct("com.sun.star.table.TableSortField");
$fields[0]->{Field} = 7; # column number
$fields[0]->{IsAscending} = 0;
$unoWrap = $objServiceManager->Bridge_GetValueObject;
$unoWrap->Set ("[]com.sun.star.table.TableSortField", \@fields);
$sortDx = $range->createSortDescriptor();
$sortDx->[0]->{Name} = "ContainsHeader";
$sortDx->[0]->{Value} = 1;
$sortDx->[3]->{Name} = "SortFields";
$sortDx->[3]->{Value} = $unoWrap;
#$sortDx->[3]->{Value} = \@fields; # You would think this would work? It doesn't.
$range->sort($sortDx);


# create a new sheet to paste to
$calc->getSheets->insertNewByName("NewSheet", 1 );
$sheet2 = $calc->getSheets->getByIndex(1);
$calc->CurrentController->Select($sheet2);

# copy row
$pasteHere = $sheet2->getCellByPosition(0, 0)->CellAddress;
$copyRange = $oSheet->getCellRangeByName("A1:Q1")->RangeAddress;
$oSheet->copyRange($pasteHere, $copyRange);

$cellValue = $sheet2->getCellByPosition(16, $row)->getValue()); # get cell value as integer
$date = $sheet2->getCellByPosition(5, $row)->getString(); # must get dates as strings

$calc->getCurrentController->getFrame->getContainerWindow()->setVisible(1); # set visible
$calc->close(0); # close program window
#print Win32::OLE->LastError, "\n";

[/code]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文