Convert SpreadSheets to CSV files with Python and pyuno
Using the OORunner class that we developed last week we'll now create a Python class for converting spreadsheets into CSV files. The converter supports any type of input spreadsheet that is supported by OpenOffice.
When run the program takes pairs of input and output files, for example:
$ python ssconverter.py file1.xls file1.csv file2.ods file2.csv
Each input file is a spreadsheet and it is converted into the corresponding output file as a CSV file.
The meat of the operation happens in the convert function from the SSConverter class. The first thing it does is start OpenOffice running using the OORunner class. It then converts the input and output file names to URLs and uses the desktop object returned by OORunner to create and load a document object. Converting the spreadsheet to a CSV file is merely a matter of saving the document to the output URL. The source code for the SSConverter class follows:
#!/usr/bin/python # # Convert spreadsheet to CSV file. # # Based on: # PyODConverter (Python OpenDocument Converter) v1.0.0 - 2008-05-05 # Copyright (C) 2008 Mirko Nasato <email@example.com> # Licensed under the GNU LGPL v2.1 - or any later version. # http://www.gnu.org/licenses/lgpl-2.1.html # import os import ooutils import uno from com.sun.star.task import ErrorCodeIOException class SSConverter: """ Spreadsheet converter class. Converts spreadsheets to CSV files. """ def __init__(self, oorunner=None): self.desktop = None self.oorunner = None def convert(self, inputFile, outputFile): """ Convert the input file (a spreadsheet) to a CSV file. """ # Start openoffice if needed. if not self.desktop: if not self.oorunner: self.oorunner = ooutils.OORunner() self.desktop = self.oorunner.connect() inputUrl = uno.systemPathToFileUrl(os.path.abspath(inputFile)) outputUrl = uno.systemPathToFileUrl(os.path.abspath(outputFile)) document = self.desktop.loadComponentFromURL(inputUrl, "_blank", 0, ooutils.oo_properties(Hidden=True)) try: # Additional property option: # FilterOptions="59,34,0,1" # 59 - Field separator (semicolon), this is the ascii value. # 34 - Text delimiter (double quote), this is the ascii value. # 0 - Character set (system). # 1 - First line number to export. # # For more information see: # http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_Options # document.storeToURL(outputUrl, ooutils.oo_properties(FilterName="Text - txt - csv (StarCalc)")) finally: document.close(True) if __name__ == "__main__": from sys import argv from os.path import isfile if len(argv) == 2 and argv == '--shutdown': ooutils.oo_shutdown_if_running() else: if len(argv) < 3 or len(argv) % 2 != 1: print "USAGE:" print " python %s INPUT-FILE OUTPUT-FILE INPUT-FILE OUTPUT-FILE..." % argv print "OR" print " python %s --shutdown" % argv exit(255) if not isfile(argv): print "File not found: %s" % argv exit(1) try: i = 1 converter = SSConverter() while i+1 < len(argv): print '%s => %s' % (argv[i], argv[i+1]) converter.convert(argv[i], argv[i+1]) i += 2 except ErrorCodeIOException, exception: print "ERROR! ErrorCodeIOException %d" % exception.ErrCode exit(1)
As with OORunner, this code is based on PyODConverter. Next week we'll write a converter function that creates the CSV file automatically from the corresponding spreadsheet if the CSV file does not exist. In addition it will re-create the CSV file if the spreadsheet is newer than the CSV file. This way you can essentially use spreadsheets and CSV files interchangeably in your code.
Mitch Frazier is an Associate Editor for Linux Journal.
Webinar: 8 Signs You’re Beyond Cron
11am CDT, April 29th
Join Linux Journal and Pat Cameron, Director of Automation Technology at HelpSystems, as they discuss the eight primary advantages of moving beyond cron job scheduling. In this webinar, you’ll learn about integrating cron with an enterprise scheduler.Join us!
|Play for Me, Jarvis||Apr 16, 2015|
|Drupageddon: SQL Injection, Database Abstraction and Hundreds of Thousands of Web Sites||Apr 15, 2015|
|Non-Linux FOSS: .NET?||Apr 13, 2015|
|Designing Foils with XFLR5||Apr 08, 2015|
|diff -u: What's New in Kernel Development||Apr 07, 2015|
- Drupageddon: SQL Injection, Database Abstraction and Hundreds of Thousands of Web Sites
- Play for Me, Jarvis
- Non-Linux FOSS: .NET?
- Designing Foils with XFLR5
- Not So Dynamic Updates
- Flexible Access Control with Squid Proxy
- New Products
- Users, Permissions and Multitenant Sites
- diff -u: What's New in Kernel Development