Compare commits

...

10 Commits

130 changed files with 16516 additions and 38 deletions

View File

@ -261,7 +261,7 @@ class ZScoUsers(
security.declareProtected(ScoUsersAdmin, "user_info")
def user_info(self, user_name=None, user=None):
def user_info(self, user_name=None, user=None, format=None, REQUEST=None):
"""Donne infos sur l'utilisateur (qui peut ne pas etre dans notre base).
Si user_name est specifie, interroge la BD. Sinon, user doit etre un dict.
"""
@ -322,7 +322,7 @@ class ZScoUsers(
# nomnoacc est le nom en minuscules sans accents
info["nomnoacc"] = scu.suppress_accents(scu.strlower(info["nom"]))
return info
return scu.sendResult(REQUEST, info, name="user", format=format)
def _can_handle_passwd(self, authuser, user_name, allow_admindepts=False):
"""true if authuser can see or change passwd of user_name.

View File

@ -34,9 +34,11 @@ export POSTGRES_USER=www-data
if [ "${debian_version}" = "10" ]
then
PSQL=/usr/lib/postgresql/11/bin/psql
export POSTGRES_SERVICE="postgresql@11-main.service"
elif [ "${debian_version}" = "9" ]
then
PSQL=/usr/lib/postgresql/9.6/bin/psql
export POSTGRES_SERVICE="postgresql"
elif [ "${debian_version}" = "8" ]
then
PSQL=/usr/lib/postgresql/9.4/bin/psql

View File

@ -8,7 +8,13 @@ source utils.sh
check_uid_root $0
echo 'Installation du demarrage automatique de ScoDoc (systemd)'
cp $SCODOC_DIR/config/etc/scodoc.service /etc/systemd/system
# La variable POSTGRES_SERVICE doit être positionnée dans config.sh
# suivant la version de Debian et de postgresql
[ -z "${POSTGRES_SERVICE}" ] && die "incompatible Debian version"
cat "$SCODOC_DIR/config/etc/scodoc.service" | sed 's/{{postgresql}}/'"${POSTGRES_SERVICE}"'/g' > /etc/systemd/system/scodoc.service
systemctl enable scodoc.service
echo "A partir de maintenant, utiliser"

View File

@ -1,13 +1,15 @@
# ScoDoc7 service
# Zope based
# Depends on postgresql
# => is restarted when postgresql restarts
# Depends on {{postgresql}} (replaced by installation script by
# postgresql@11-main.service on Debian 10
# postgresql on Debian <= 9
# => is restarted when {{postgresql}} restarts
#
[Unit]
Description=ScoDoc 7 service
After=network.target postgresql
Requires=postgresql
PartOf=postgresql
After=network.target {{postgresql}}
Requires={{postgresql}}
PartOf={{postgresql}}
StartLimitIntervalSec=0
[Service]
@ -21,4 +23,4 @@ ExecStop=/opt/scodoc/bin/zopectl stop
ExecReload=/opt/scodoc/bin/zopectl restart
[Install]
WantedBy=postgresql
WantedBy={{postgresql}}

View File

@ -220,9 +220,7 @@ read ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
# ScoDoc 7.19+ uses systemd
echo 'Installation du demarrage automatique de ScoDoc (systemd)'
cp $SCODOC_DIR/config/etc/scodoc.service /etc/systemd/system
systemctl enable scodoc.service
$SCODOC_DIR/config/configure_systemd.sh
fi

View File

@ -0,0 +1 @@
build

View File

@ -0,0 +1,68 @@
0.4.0a (27.03.2005)
---------
* First public version
0.5.0a (11.05.2005)
---------
* pyExcelerator now can import Excel 5/95/97/2000/XP/2003 files.
With imported information you can do what you want.
See ./examples/xls2txt.py for reference.
* fixed bug in MS OLE2 compound document dumper (not in writer :))
Bug causes dumper to combine links in sectors' allocation chain sectors
contained in additional MSAT with SAT data.
* Excel files dumper supports now Excel 5/95/97/2000/XP/2003 files
and produces more informative output.
0.5.1a (14.05.2005)
---------
* improved floating point decoding code
0.5.2a (18.05.2005)
---------
* improved perfomance (especially on nonfragmented streams)
* now pyExcelerator can process XLS files with short streams
* OLE2 compound document dumper supports short streams
* reading UTF-16-LE and Latin-1 with more accuracy
* in DSF (double stream file) XLS data extracted from stream "Workbook"
* improved floating point/integer values decoding code
0.5.3a (19.05.2005)
---------
* typos in biff-dumper.py fixed :(
* now pyExcelerator can correctly import XLS files with charts
* added ability to override default file's encoding
* new examples (or tools :)) -- ./examples/xls2csv.py, ./examples/xls2html.py
0.6.0a (19.07.2005)
---------
* blanks, numbers, currency (use number formats!) and dates (use number formats!)
* pyExcelerator uses 1.5-2 times less memory (thanks to __brains__ and __slots__)
* fixes for Big Endian CPUs
* some refactorings
* new examples: blanks.py, merged1.py, dates.py, numbers.py, num_formats.py, formulas.py
* most important change: formulas support
0.6.1a (29.09.2005)
---------
* fixed: exception when reading OLE2 files with incorrect MSAT
(sector ids points to nonexistense sectors)
0.6.2a (30.09.2005)
---------
* fixed: exception when reading OLE2 files with incorrect SSAT
(sector ids points to nonexistense sectors)
0.6.3a (25.10.2005)
---------
* slightly new algorithm for reading OLE2 files. I hope it is
more robust
* splitting and frozing
* worksheet protection
* protection password
* workbook protection
* new example: protection.py, hyperlinks.py, panes.py
* extracting formula results
* speed optmizations(for example, benchmark big-35Mb.py runs about
20-30% faster)
* updated THANKS file
* xls2csv, xls2txt, xls2html now resides in ./tools

View File

@ -0,0 +1,13 @@
/.cvsignore/1.1/Thu May 19 09:27:42 2005//
D/examples////
D/hrc////
D/museum////
D/pyExcelerator////
D/tools////
/LICENSE.txt/1.3/Tue Jul 19 18:58:44 2005//
/README.txt/1.3/Sat Aug 13 23:25:44 2005//
/TODO.txt/1.2/Wed Aug 10 20:42:08 2005//
/CHANGES.txt/1.11/Tue Oct 25 19:34:26 2005//
/PKG-INFO/1.5/Tue Oct 4 20:19:20 2005//
/THANKS.txt/1.3/Thu Oct 20 20:46:16 2005//
/setup.py/1.10/Wed Oct 26 07:44:23 2005//

View File

@ -0,0 +1,13 @@
/.cvsignore////*///
D/examples///////
D/hrc///////
D/museum///////
D/pyExcelerator///////
D/tools///////
/LICENSE.txt////*///
/README.txt////*///
/TODO.txt////*///
/CHANGES.txt////*///
/PKG-INFO////*///
/THANKS.txt////*///
/setup.py////*///

View File

@ -0,0 +1,13 @@
/.cvsignore////*///
D/examples///////
D/hrc///////
D/museum///////
D/pyExcelerator///////
D/tools///////
/LICENSE.txt////*///
/THANKS.txt////*///
/README.txt////*///
/TODO.txt////*///
/CHANGES.txt////*///
/PKG-INFO////*///
/setup.py////*///

View File

@ -0,0 +1,13 @@
/.cvsignore/1.1/Thu May 19 09:27:42 2005//
D/examples////
D/hrc////
D/museum////
D/pyExcelerator////
D/tools////
/LICENSE.txt/1.3/Tue Jul 19 18:58:44 2005//
/THANKS.txt/1.2/Thu Sep 29 18:06:58 2005//
/README.txt/1.3/Sat Aug 13 23:25:44 2005//
/TODO.txt/1.2/Wed Aug 10 20:42:08 2005//
/CHANGES.txt/1.10/Fri Sep 30 09:14:44 2005//
/PKG-INFO/1.4/Fri Sep 30 09:13:49 2005//
/setup.py/1.9/Fri Sep 30 09:20:04 2005//

View File

@ -0,0 +1 @@
pyExcelerator

View File

@ -0,0 +1 @@
:ext:rvk@cvs.sf.net:/cvsroot/pyexcelerator

View File

@ -0,0 +1,47 @@
Copyright (C) 2005 Roman V. Kiseliov
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. All advertising materials mentioning features or use of this
software must display the following acknowledgment:
"This product includes software developed by
Roman V. Kiseliov <roman@kiseliov.ru>."
4. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes software developed by
Roman V. Kiseliov <roman@kiseliov.ru>."
THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
Roman V. Kiseliov
Russia
Kursk
Libknecht St., 4
+7(0712)56-09-83
<roman@kiseliov.ru>
Subject: pyExcelerator

View File

@ -0,0 +1,20 @@
Metadata-Version: 1.0
Name: pyExcelerator
Version: 0.6.3a1
Summary: Library to generate Microsoft Excel (tm) spreadsheet files or to extract data from such files
Home-page: http://www.sourceforge.net/projects/pyexcelerator
Author: Roman V. Kiseliov
Author-email: roman@kiseliov.ru
License: BSD
Download-URL: http://www.sourceforge.net/projects/pyexcelerator
Description: Generate Excel 97+ files. Extract data from Excel 95+ spreadsheets. Full-blown UNICODE support. Pure Python code.
Keywords: xls,excel,spreadsheet,workbook
Platform: Platform-independent
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python
Classifier: Operating System :: OS Independent
Classifier: Topic :: Database
Classifier: Topic :: Office/Business
Classifier: Topic :: Software Development :: Libraries :: Python Modules

View File

@ -0,0 +1,145 @@
pyExcelerator
--------------------
Dedicated to Olya.
With you it can be reality.
0x0000. What's this?
--------------------
This is a library for generating Excel 97/2000/XP/2003 and
OpenOffice Calc compatible spreadsheets. pyExcelerator has
full-blown support for UNICODE in Excel and Calc spreadsheets, allows
using variety of formatting features, provides interface to printing
options of Excel and OpenOffice Calc. pyExcelerator contains also
Excel BIFF8 dumper and MS compound documents dumper. Main advantage is
possibility of generating Excel spreadsheets without MS Windows and/or
COM servers. The only requirement -- Python 2.4a3 or higher.
0x0001. Why?
--------------------
I had need to generate .xls with UNICODE under FreeBSD.
0x0002. Requirements.
--------------------
Python 2.4 up and running. I've tested pyExcelerator under
Win32 (Python compiled with MS C compiler and Intel
C compiler), Win64-x86 (MS C compiler), FreeBSD/i386 (GCC
3.4.2), FreeBSD/amd64 (GCC 3.4.2). Fastest was Python under
FreeBSD/amd64.
0x0003. Installation.
--------------------
As usually: python ./setup.py install
0x0004. Documentation.
--------------------
In progress. At the present time you can use examples and sources (I hope
I commented sources well and gave variables good names).
0x0005. Extra features.
--------------------
See ./tools/*.py. You'll find there BIFF8 dumper and MS Compound doc
dumper. In ./hrc you can take my python.hrc for Colorer plug-in for FAR
manager.
0x0006. Reporting bugs.
--------------------
Please!
0x0008. Future.
--------------------
Support for Esher layer and (maybe) charts.
0x0009. Useful links.
--------------------
http://www.python.org --
Python's home.
http://sf.net/pyXLWriter --
port of the first version Spreadsheet-WriteExcel.
This library can write only BIFF5/7 spreadsheets
and therefore can't use UNICODE in spreadsheets.
pyXLWriter however can write formulas with help
of PLY. IMHO, PLY and ambiguous grammar used by
author for formulas support are too power tools.
But in this case power was equals to simplicity.
I want overcome these restrictions and (strictly
IMHO) misfeatures.
http://www.openoffice.org --
OpenOffice home.
About 650 Mb sources -- the best teachers.
0x000A. Legality.
--------------------
With help from lawyers pyExcelerator is protect by Russian Federation's
laws and international treaties and can be used iff you agreed following
BSD-like agreement.
Copyright (C) 2005 Roman V. Kiseliov
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. All advertising materials mentioning features or use of this
software must display the following acknowledgment:
"This product includes software developed by
Roman V. Kiseliov <roman@kiseliov.ru>."
4. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes software developed by
Roman V. Kiseliov <roman@kiseliov.ru>."
THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
0xFFFF. Contacting author.
--------------------
Feel free to send me feedback and bug reports.
Roman V. Kiseliov
Russia
Kursk
Libknecht St., 4
+7(0712)56-09-83
<roman@kiseliov.ru>
subject *must* be
"pyExcelerator-bug" (without quotes)
or
"pyExcelerator-feedback" (without quotes)

View File

@ -0,0 +1,25 @@
* My lovely wife Olya
--------------------------
* Evgeny Filatov
* John McNamara
* Daniel Rentz
* John Machin
* Ksenia Marasanova
* Choe, Cheng-Dae
* Jan ONDREJ
* Andy Gimblett
* Blais, Gerard C.
* McNevin Michael B.
* John Fouby
* <your name>. Feel free to update my memory!
--------------------------
* Offspring
* Lynkin Park
--------------------------
* Nescafe
--------------------------
* Python Team
* FreeBSD Team
* SF Team

View File

@ -0,0 +1,2 @@
*Write documentation
*BSE container for Esher layer

View File

@ -0,0 +1,32 @@
/big-16Mb.py/1.3/Sun Mar 27 12:47:06 2005//
/big-35Mb.py/1.3/Sun Mar 27 12:47:06 2005//
/blanks.py/1.2/Fri Jul 22 08:22:26 2005//
/col_width.py/1.3/Sun Mar 27 12:47:06 2005//
/format.py/1.3/Sun Mar 27 12:47:06 2005//
/image.py/1.3/Sun Mar 27 12:47:06 2005//
/merged.py/1.3/Sun Mar 27 12:47:06 2005//
/merged0.py/1.3/Sun Mar 27 12:47:06 2005//
/merged1.py/1.1/Fri Jul 22 08:22:26 2005//
/mini.py/1.3/Sun Mar 27 12:47:06 2005//
/outline.py/1.3/Sun Mar 27 12:47:06 2005//
/row_styles.py/1.3/Sun Mar 27 12:47:06 2005//
/row_styles_empty.py/1.3/Sun Mar 27 12:47:06 2005//
/sst.py/1.2/Fri Mar 25 07:31:12 2005//
/unicode0.py/1.1/Sun Mar 27 12:47:06 2005//
/unicode1.py/1.1/Sun Mar 27 12:47:06 2005//
/unicode2.py/1.1/Sun Mar 27 12:47:06 2005//
/wsprops.py/1.3/Sun Mar 27 12:47:06 2005//
/xls2csv.py/1.1/Thu May 19 09:27:42 2005//
/xls2html.py/1.1/Thu May 19 09:27:42 2005//
/xls2txt.py/1.3/Thu May 19 09:27:42 2005//
/python.bmp/1.1/Tue Jul 19 18:58:44 2005/-kb/
/formula_names.py/1.1/Thu Aug 11 08:53:48 2005//
/parse-fmla.py/1.1/Wed Aug 10 21:08:02 2005//
/dates.py/1.1/Wed Jul 20 07:24:10 2005//
/num_formats.py/1.1/Wed Jul 20 07:24:10 2005//
/numbers.py/1.1/Wed Jul 20 07:24:10 2005//
/formulas.py/1.4/Wed Oct 26 07:44:24 2005//
/hyperlinks.py/1.1/Wed Oct 26 07:44:24 2005//
/panes.py/1.1/Wed Oct 26 07:44:24 2005//
/protection.py/1.1/Wed Oct 26 07:44:24 2005//
D

View File

@ -0,0 +1,31 @@
/big-16Mb.py////*///
/big-35Mb.py////*///
/blanks.py////*///
/col_width.py////*///
/format.py////*///
/image.py////*///
/merged.py////*///
/merged0.py////*///
/merged1.py////*///
/mini.py////*///
/outline.py////*///
/row_styles.py////*///
/row_styles_empty.py////*///
/sst.py////*///
/unicode0.py////*///
/unicode1.py////*///
/unicode2.py////*///
/wsprops.py////*///
/xls2csv.py////*///
/xls2html.py////*///
/xls2txt.py////*///
/python.bmp////*///
/formula_names.py////*///
/parse-fmla.py////*///
/dates.py////*///
/num_formats.py////*///
/numbers.py////*///
/formulas.py////*///
/hyperlinks.py////*///
/panes.py////*///
/protection.py////*///

View File

@ -0,0 +1,31 @@
/big-16Mb.py////*///
/big-35Mb.py////*///
/blanks.py////*///
/col_width.py////*///
/format.py////*///
/image.py////*///
/merged.py////*///
/merged0.py////*///
/merged1.py////*///
/mini.py////*///
/outline.py////*///
/row_styles.py////*///
/row_styles_empty.py////*///
/sst.py////*///
/unicode0.py////*///
/unicode1.py////*///
/unicode2.py////*///
/wsprops.py////*///
/xls2csv.py////*///
/xls2html.py////*///
/xls2txt.py////*///
/python.bmp////*///
/formula_names.py////*///
/parse-fmla.py////*///
/dates.py////*///
/formulas.py////*///
/num_formats.py////*///
/numbers.py////*///
/hyperlinks.py////*///
/panes.py////*///
/protection.py////*///

View File

@ -0,0 +1,32 @@
/big-16Mb.py/1.3/Sun Mar 27 12:47:06 2005//
/big-35Mb.py/1.3/Sun Mar 27 12:47:06 2005//
/blanks.py/1.2/Fri Jul 22 08:22:26 2005//
/col_width.py/1.3/Sun Mar 27 12:47:06 2005//
/format.py/1.3/Sun Mar 27 12:47:06 2005//
/image.py/1.3/Sun Mar 27 12:47:06 2005//
/merged.py/1.3/Sun Mar 27 12:47:06 2005//
/merged0.py/1.3/Sun Mar 27 12:47:06 2005//
/merged1.py/1.1/Fri Jul 22 08:22:26 2005//
/mini.py/1.3/Sun Mar 27 12:47:06 2005//
/outline.py/1.3/Sun Mar 27 12:47:06 2005//
/row_styles.py/1.3/Sun Mar 27 12:47:06 2005//
/row_styles_empty.py/1.3/Sun Mar 27 12:47:06 2005//
/sst.py/1.2/Fri Mar 25 07:31:12 2005//
/unicode0.py/1.1/Sun Mar 27 12:47:06 2005//
/unicode1.py/1.1/Sun Mar 27 12:47:06 2005//
/unicode2.py/1.1/Sun Mar 27 12:47:06 2005//
/wsprops.py/1.3/Sun Mar 27 12:47:06 2005//
/xls2csv.py/1.1/Thu May 19 09:27:42 2005//
/xls2html.py/1.1/Thu May 19 09:27:42 2005//
/xls2txt.py/1.3/Thu May 19 09:27:42 2005//
/python.bmp/1.1/Tue Jul 19 18:58:44 2005/-kb/
/formula_names.py/1.1/Thu Aug 11 08:53:48 2005//
/parse-fmla.py/1.1/Wed Aug 10 21:08:02 2005//
/dates.py/1.1/Wed Jul 20 07:24:10 2005//
/formulas.py/1.3/Sun Aug 14 06:40:22 2005//
/num_formats.py/1.1/Wed Jul 20 07:24:10 2005//
/numbers.py/1.1/Wed Jul 20 07:24:10 2005//
/hyperlinks.py/0/dummy timestamp//
/panes.py/0/dummy timestamp//
/protection.py/0/dummy timestamp//
D

View File

@ -0,0 +1 @@
pyExcelerator/examples

View File

@ -0,0 +1 @@
:ext:rvk@cvs.sf.net:/cvsroot/pyexcelerator

View File

@ -0,0 +1,37 @@
#!/usr/bin/env python
# tries stress SST, SAT and MSAT
__rev_id__ = """$Id: big-16Mb.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from time import *
from pyExcelerator.Workbook import *
from pyExcelerator.Style import *
style = XFStyle()
wb = Workbook()
ws0 = wb.add_sheet('0')
colcount = 200 + 1
rowcount = 6000 + 1
t0 = time()
print "\nstart: %s" % ctime(t0)
print "Filling..."
for col in xrange(colcount):
print "[%d]" % col,
for row in xrange(rowcount):
#ws0.write(row, col, "BIG(%d, %d)" % (row, col))
ws0.write(row, col, "BIG")
t1 = time() - t0
print "\nsince starting elapsed %.2f s" % (t1)
print "Storing..."
wb.save('big-16Mb.xls')
t2 = time() - t0
print "since starting elapsed %.2f s" % (t2)

View File

@ -0,0 +1,36 @@
#!/usr/bin/env python
# tries stress SST, SAT and MSAT
__rev_id__ = """$Id: big-35Mb.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from time import *
from pyExcelerator import *
style = XFStyle()
wb = Workbook()
ws0 = wb.add_sheet('0')
colcount = 200 + 1
rowcount = 6000 + 1
t0 = time()
print "\nstart: %s" % ctime(t0)
print "Filling..."
for col in xrange(colcount):
print "[%d]" % col,
for row in xrange(rowcount):
ws0.write(row, col, "BIG(%d, %d)" % (row, col))
#ws0.write(row, col, "BIG")
t1 = time() - t0
print "\nsince starting elapsed %.2f s" % (t1)
print "Storing..."
wb.save('big-35Mb.xls')
t2 = time() - t0
print "since starting elapsed %.2f s" % (t2)

View File

@ -0,0 +1,39 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: blanks.py,v 1.2 2005/07/22 08:22:26 rvk Exp $"""
from pyExcelerator import *
font0 = Font()
font0.name = 'Times New Roman'
font0.struck_out = True
font0.bold = True
style0 = XFStyle()
style0.font = font0
wb = Workbook()
ws0 = wb.add_sheet('0')
ws0.write(1, 1, 'Test', style0)
for i in range(0, 0x53):
borders = Borders()
borders.left = i
borders.right = i
borders.top = i
borders.bottom = i
style = XFStyle()
style.borders = borders
ws0.write(i, 2, '', style)
ws0.write(i, 3, hex(i), style0)
ws0.write_merge(5, 8, 6, 10, "")
wb.save('blanks.xls')

View File

@ -0,0 +1,19 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: col_width.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('Hey, Dude')
for i in range(6, 80):
fnt = Font()
fnt.height = i*20
style = XFStyle()
style.font = fnt
ws.write(1, i, 'Test')
ws.col(i).width = 0x0d00 + i
w.save('col_width.xls')

View File

@ -0,0 +1,39 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: dates.py,v 1.1 2005/07/20 07:24:11 rvk Exp $"""
from pyExcelerator import *
from datetime import datetime
w = Workbook()
ws = w.add_sheet('Hey, Dude')
fmts = [
'M/D/YY',
'D-MMM-YY',
'D-MMM',
'MMM-YY',
'h:mm AM/PM',
'h:mm:ss AM/PM',
'h:mm',
'h:mm:ss',
'M/D/YY h:mm',
'mm:ss',
'[h]:mm:ss',
'mm:ss.0',
]
i = 0
for fmt in fmts:
ws.write(i, 0, fmt)
style = XFStyle()
style.num_format_str = fmt
ws.write(i, 4, datetime.now(), style)
i += 1
w.save('dates.xls')

View File

@ -0,0 +1,41 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: format.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
font0 = Font()
font0.name = 'Times New Roman'
font0.struck_out = True
font0.bold = True
style0 = XFStyle()
style0.font = font0
wb = Workbook()
ws0 = wb.add_sheet('0')
ws0.write(1, 1, 'Test', style0)
for i in range(0, 0x53):
fnt = Font()
fnt.name = 'Arial'
fnt.colour_index = i
fnt.outline = True
borders = Borders()
borders.left = i
style = XFStyle()
style.font = fnt
style.borders = borders
ws0.write(i, 2, 'colour', style)
ws0.write(i, 3, hex(i), style0)
wb.save('format.xls')

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: formula_names.py,v 1.1 2005/08/11 08:53:48 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('F')
i = 0
for n in sorted(ExcelMagic.std_func_by_name):
ws.write(i, 0, n)
ws.write(i, 3, Formula(n + "($A$1)"))
i += 1
w.save('formula_names.xls')

View File

@ -0,0 +1,49 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: formulas.py,v 1.4 2005/10/26 07:44:24 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('F')
ws.write(0, 0, Formula("-(1+1)"))
ws.write(1, 0, Formula("-(1+1)/(-2-2)"))
ws.write(2, 0, Formula("-(134.8780789+1)"))
ws.write(3, 0, Formula("-(134.8780789e-10+1)"))
ws.write(4, 0, Formula("-1/(1+1)+9344"))
ws.write(0, 1, Formula("-(1+1)"))
ws.write(1, 1, Formula("-(1+1)/(-2-2)"))
ws.write(2, 1, Formula("-(134.8780789+1)"))
ws.write(3, 1, Formula("-(134.8780789e-10+1)"))
ws.write(4, 1, Formula("-1/(1+1)+9344"))
ws.write(0, 2, Formula("A1*B1"))
ws.write(1, 2, Formula("A2*B2"))
ws.write(2, 2, Formula("A3*B3"))
ws.write(3, 2, Formula("A4*B4*sin(pi()/4)"))
ws.write(4, 2, Formula("A5%*B5*pi()/1000"))
##############
## NOTE: parameters are separated by semicolon!!!
##############
ws.write(5, 2, Formula("C1+C2+C3+C4+C5/(C1+C2+C3+C4/(C1+C2+C3+C4/(C1+C2+C3+C4)+C5)+C5)-20.3e-2"))
ws.write(5, 3, Formula("C1^2"))
ws.write(6, 2, Formula("SUM(C1;C2;;;;;C3;;;C4)"))
ws.write(6, 3, Formula("SUM($A$1:$C$5)"))
ws.write(7, 0, Formula('"lkjljllkllkl"'))
ws.write(7, 1, Formula('"yuyiyiyiyi"'))
ws.write(7, 2, Formula('A8 & B8 & A8'))
ws.write(8, 2, Formula('now()'))
ws.write(10, 2, Formula('TRUE'))
ws.write(11, 2, Formula('FALSE'))
ws.write(12, 3, Formula('IF(A1>A2;3;"hkjhjkhk")'))
w.save('formulas.xls')

View File

@ -0,0 +1,30 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: hyperlinks.py,v 1.1 2005/10/26 07:44:24 rvk Exp $"""
from pyExcelerator import *
f = Font()
f.height = 20*72
f.name = 'Verdana'
f.bold = True
f.underline = Font.UNDERLINE_DOUBLE
f.colour_index = 4
h_style = XFStyle()
h_style.font = f
w = Workbook()
ws = w.add_sheet('F')
##############
## NOTE: parameters are separated by semicolon!!!
##############
n = "HYPERLINK"
ws.write_merge(1, 1, 1, 10, Formula(n + '("http://www.irs.gov/pub/irs-pdf/f1000.pdf";"f1000.pdf")'), h_style)
ws.write_merge(2, 2, 2, 25, Formula(n + '("mailto:roman.kiseliov@gmail.com?subject=pyExcelerator-feedback&Body=Hello,%20Roman!";"pyExcelerator-feedback")'), h_style)
w.save("hyperlinks.xls")

View File

@ -0,0 +1,15 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: image.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('Image')
ws.insert_bitmap('python.bmp', 2, 2)
ws.insert_bitmap('python.bmp', 10, 2)
w.save('image.xls')

View File

@ -0,0 +1,42 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: merged.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
fnt = Font()
fnt.name = 'Arial'
fnt.colour_index = 4
fnt.bold = True
borders = Borders()
borders.left = 6
borders.right = 6
borders.top = 6
borders.bottom = 6
al = Alignment()
al.horz = Alignment.HORZ_CENTER
al.vert = Alignment.VERT_CENTER
style = XFStyle()
style.font = fnt
style.borders = borders
style.alignment = al
wb = Workbook()
ws0 = wb.add_sheet('sheet0')
ws1 = wb.add_sheet('sheet1')
ws2 = wb.add_sheet('sheet2')
for i in range(0, 0x200, 2):
ws0.write_merge(i, i+1, 1, 5, 'test %d' % i, style)
ws1.write_merge(i, i, 1, 7, 'test %d' % i, style)
ws2.write_merge(i, i+1, 1, 7 + (i%10), 'test %d' % i, style)
wb.save('merged.xls')

View File

@ -0,0 +1,32 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: merged0.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
wb = Workbook()
ws0 = wb.add_sheet('sheet0')
fnt = Font()
fnt.name = 'Arial'
fnt.colour_index = 4
fnt.bold = True
borders = Borders()
borders.left = 6
borders.right = 6
borders.top = 6
borders.bottom = 6
style = XFStyle()
style.font = fnt
style.borders = borders
ws0.write_merge(3, 3, 1, 5, 'test1', style)
ws0.write_merge(4, 10, 1, 5, 'test2', style)
ws0.col(1).width = 0x0d00
wb.save('merged0.xls')

View File

@ -0,0 +1,104 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: merged1.py,v 1.1 2005/07/22 08:22:26 rvk Exp $"""
from pyExcelerator import *
wb = Workbook()
ws0 = wb.add_sheet('sheet0')
fnt1 = Font()
fnt1.name = 'Verdana'
fnt1.bold = True
fnt1.height = 18*0x14
pat1 = Pattern()
pat1.pattern = Pattern.SOLID_PATTERN
pat1.pattern_fore_colour = 0x16
brd1 = Borders()
brd1.left = 0x06
brd1.right = 0x06
brd1.top = 0x06
brd1.bottom = 0x06
fnt2 = Font()
fnt2.name = 'Verdana'
fnt2.bold = True
fnt2.height = 14*0x14
brd2 = Borders()
brd2.left = 0x01
brd2.right = 0x01
brd2.top = 0x01
brd2.bottom = 0x01
pat2 = Pattern()
pat2.pattern = Pattern.SOLID_PATTERN
pat2.pattern_fore_colour = 0x01F
fnt3 = Font()
fnt3.name = 'Verdana'
fnt3.bold = True
fnt3.italic = True
fnt3.height = 12*0x14
brd3 = Borders()
brd3.left = 0x07
brd3.right = 0x07
brd3.top = 0x07
brd3.bottom = 0x07
fnt4 = Font()
al1 = Alignment()
al1.horz = Alignment.HORZ_CENTER
al1.vert = Alignment.VERT_CENTER
al2 = Alignment()
al2.horz = Alignment.HORZ_RIGHT
al2.vert = Alignment.VERT_CENTER
al3 = Alignment()
al3.horz = Alignment.HORZ_LEFT
al3.vert = Alignment.VERT_CENTER
style1 = XFStyle()
style1.font = fnt1
style1.alignment = al1
style1.pattern = pat1
style1.borders = brd1
style2 = XFStyle()
style2.font = fnt2
style2.alignment = al1
style2.pattern = pat2
style2.borders = brd2
style3 = XFStyle()
style3.font = fnt3
style3.alignment = al1
style3.pattern = pat2
style3.borders = brd3
price_style = XFStyle()
price_style.font = fnt4
price_style.alignment = al2
price_style.borders = brd3
price_style.num_format_str = '_(#,##0.00_) "money"'
ware_style = XFStyle()
ware_style.font = fnt4
ware_style.alignment = al3
ware_style.borders = brd3
ws0.merge(3, 3, 1, 5, style1)
ws0.merge(4, 10, 1, 6, style2)
ws0.merge(14, 16, 1, 7, style3)
ws0.col(1).width = 0x0d00
wb.save('merged1.xls')

View File

@ -0,0 +1,11 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: mini.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('Hey, Dude')
w.save('mini.xls')

View File

@ -0,0 +1,62 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: num_formats.py,v 1.1 2005/07/20 07:24:11 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('Hey, Dude')
fmts = [
'general',
'0',
'0.00',
'#,##0',
'#,##0.00',
'"$"#,##0_);("$"#,##',
'"$"#,##0_);[Red]("$"#,##',
'"$"#,##0.00_);("$"#,##',
'"$"#,##0.00_);[Red]("$"#,##',
'0%',
'0.00%',
'0.00E+00',
'# ?/?',
'# ??/??',
'M/D/YY',
'D-MMM-YY',
'D-MMM',
'MMM-YY',
'h:mm AM/PM',
'h:mm:ss AM/PM',
'h:mm',
'h:mm:ss',
'M/D/YY h:mm',
'_(#,##0_);(#,##0)',
'_(#,##0_);[Red](#,##0)',
'_(#,##0.00_);(#,##0.00)',
'_(#,##0.00_);[Red](#,##0.00)',
'_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)',
'_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)',
'_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)',
'_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)',
'mm:ss',
'[h]:mm:ss',
'mm:ss.0',
'##0.0E+0',
'@'
]
i = 0
for fmt in fmts:
ws.write(i, 0, fmt)
style = XFStyle()
style.num_format_str = fmt
ws.write(i, 4, -1278.9078, style)
i += 1
w.save('num_formats.xls')

View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: numbers.py,v 1.1 2005/07/20 07:24:11 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('Hey, Dude')
ws.write(0, 0, 1)
ws.write(1, 0, 1.23)
ws.write(2, 0, 12345678)
ws.write(3, 0, 123456.78)
ws.write(0, 1, -1)
ws.write(1, 1, -1.23)
ws.write(2, 1, -12345678)
ws.write(3, 1, -123456.78)
ws.write(0, 2, -17867868678687.0)
ws.write(1, 2, -1.23e-5)
ws.write(2, 2, -12345678.90780980)
ws.write(3, 2, -123456.78)
w.save('numbers.xls')

View File

@ -0,0 +1,115 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: outline.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
fnt = Font()
fnt.name = 'Arial'
fnt.colour_index = 4
fnt.bold = True
borders = Borders()
borders.left = 6
borders.right = 6
borders.top = 6
borders.bottom = 6
style = XFStyle()
style.font = fnt
style.borders = borders
wb = Workbook()
ws0 = wb.add_sheet('Rows Outline')
ws0.write_merge(1, 1, 1, 5, 'test 1', style)
ws0.write_merge(2, 2, 1, 4, 'test 1', style)
ws0.write_merge(3, 3, 1, 3, 'test 2', style)
ws0.write_merge(4, 4, 1, 4, 'test 1', style)
ws0.write_merge(5, 5, 1, 4, 'test 3', style)
ws0.write_merge(6, 6, 1, 5, 'test 1', style)
ws0.write_merge(7, 7, 1, 5, 'test 4', style)
ws0.write_merge(8, 8, 1, 4, 'test 1', style)
ws0.write_merge(9, 9, 1, 3, 'test 5', style)
ws0.row(1).level = 1
ws0.row(2).level = 1
ws0.row(3).level = 2
ws0.row(4).level = 2
ws0.row(5).level = 2
ws0.row(6).level = 2
ws0.row(7).level = 2
ws0.row(8).level = 1
ws0.row(9).level = 1
ws1 = wb.add_sheet('Columns Outline')
ws1.write_merge(1, 1, 1, 5, 'test 1', style)
ws1.write_merge(2, 2, 1, 4, 'test 1', style)
ws1.write_merge(3, 3, 1, 3, 'test 2', style)
ws1.write_merge(4, 4, 1, 4, 'test 1', style)
ws1.write_merge(5, 5, 1, 4, 'test 3', style)
ws1.write_merge(6, 6, 1, 5, 'test 1', style)
ws1.write_merge(7, 7, 1, 5, 'test 4', style)
ws1.write_merge(8, 8, 1, 4, 'test 1', style)
ws1.write_merge(9, 9, 1, 3, 'test 5', style)
ws1.col(1).level = 1
ws1.col(2).level = 1
ws1.col(3).level = 2
ws1.col(4).level = 2
ws1.col(5).level = 2
ws1.col(6).level = 2
ws1.col(7).level = 2
ws1.col(8).level = 1
ws1.col(9).level = 1
ws2 = wb.add_sheet('Rows and Columns Outline')
ws2.write_merge(1, 1, 1, 5, 'test 1', style)
ws2.write_merge(2, 2, 1, 4, 'test 1', style)
ws2.write_merge(3, 3, 1, 3, 'test 2', style)
ws2.write_merge(4, 4, 1, 4, 'test 1', style)
ws2.write_merge(5, 5, 1, 4, 'test 3', style)
ws2.write_merge(6, 6, 1, 5, 'test 1', style)
ws2.write_merge(7, 7, 1, 5, 'test 4', style)
ws2.write_merge(8, 8, 1, 4, 'test 1', style)
ws2.write_merge(9, 9, 1, 3, 'test 5', style)
ws2.row(1).level = 1
ws2.row(2).level = 1
ws2.row(3).level = 2
ws2.row(4).level = 2
ws2.row(5).level = 2
ws2.row(6).level = 2
ws2.row(7).level = 2
ws2.row(8).level = 1
ws2.row(9).level = 1
ws2.write_merge(1, 1, 1, 5, 'test 1', style)
ws2.write_merge(2, 2, 1, 4, 'test 1', style)
ws2.write_merge(3, 3, 1, 3, 'test 2', style)
ws2.write_merge(4, 4, 1, 4, 'test 1', style)
ws2.write_merge(5, 5, 1, 4, 'test 3', style)
ws2.write_merge(6, 6, 1, 5, 'test 1', style)
ws2.write_merge(7, 7, 1, 5, 'test 4', style)
ws2.write_merge(8, 8, 1, 4, 'test 1', style)
ws2.write_merge(9, 9, 1, 3, 'test 5', style)
ws2.col(1).level = 1
ws2.col(2).level = 1
ws2.col(3).level = 2
ws2.col(4).level = 2
ws2.col(5).level = 2
ws2.col(6).level = 2
ws2.col(7).level = 2
ws2.col(8).level = 1
ws2.col(9).level = 1
wb.save('outline.xls')

View File

@ -0,0 +1,60 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: panes.py,v 1.1 2005/10/26 07:44:24 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws1 = w.add_sheet('sheet 1')
ws2 = w.add_sheet('sheet 2')
ws3 = w.add_sheet('sheet 3')
ws4 = w.add_sheet('sheet 4')
ws5 = w.add_sheet('sheet 5')
ws6 = w.add_sheet('sheet 6')
for i in range(0x100):
ws1.write(i/0x10, i%0x10, i)
for i in range(0x100):
ws2.write(i/0x10, i%0x10, i)
for i in range(0x100):
ws3.write(i/0x10, i%0x10, i)
for i in range(0x100):
ws4.write(i/0x10, i%0x10, i)
for i in range(0x100):
ws5.write(i/0x10, i%0x10, i)
for i in range(0x100):
ws6.write(i/0x10, i%0x10, i)
ws1.panes_frozen = True
ws1.horz_split_pos = 2
ws2.panes_frozen = True
ws2.vert_split_pos = 2
ws3.panes_frozen = True
ws3.horz_split_pos = 1
ws3.vert_split_pos = 1
ws4.panes_frozen = False
ws4.horz_split_pos = 12
ws4.horz_split_first_visible = 2
ws5.panes_frozen = False
ws5.vert_split_pos = 40
ws4.vert_split_first_visible = 2
ws6.panes_frozen = False
ws6.horz_split_pos = 12
ws4.horz_split_first_visible = 2
ws6.vert_split_pos = 40
ws4.vert_split_first_visible = 2
w.save('panes.xls')

View File

@ -0,0 +1,12 @@
from pyExcelerator import ExcelFormulaParser, ExcelFormula
import sys
f = ExcelFormula.Formula(
""" -((1.80 + 2.898 * 1)/(1.80 + 2.898))*
AVERAGE((1.80 + 2.898 * 1)/(1.80 + 2.898);
(1.80 + 2.898 * 1)/(1.80 + 2.898);
(1.80 + 2.898 * 1)/(1.80 + 2.898)) +
SIN(PI()/4)""")
#for t in f.rpn():
# print "%15s %15s" % (ExcelFormulaParser.PtgNames[t[0]], t[1])

View File

@ -0,0 +1,136 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: protection.py,v 1.1 2005/10/26 07:44:24 rvk Exp $"""
from pyExcelerator import *
fnt = Font()
fnt.name = 'Arial'
fnt.colour_index = 4
fnt.bold = True
borders = Borders()
borders.left = 6
borders.right = 6
borders.top = 6
borders.bottom = 6
style = XFStyle()
style.font = fnt
style.borders = borders
wb = Workbook()
ws0 = wb.add_sheet('Rows Outline')
ws0.write_merge(1, 1, 1, 5, 'test 1', style)
ws0.write_merge(2, 2, 1, 4, 'test 1', style)
ws0.write_merge(3, 3, 1, 3, 'test 2', style)
ws0.write_merge(4, 4, 1, 4, 'test 1', style)
ws0.write_merge(5, 5, 1, 4, 'test 3', style)
ws0.write_merge(6, 6, 1, 5, 'test 1', style)
ws0.write_merge(7, 7, 1, 5, 'test 4', style)
ws0.write_merge(8, 8, 1, 4, 'test 1', style)
ws0.write_merge(9, 9, 1, 3, 'test 5', style)
ws0.row(1).level = 1
ws0.row(2).level = 1
ws0.row(3).level = 2
ws0.row(4).level = 2
ws0.row(5).level = 2
ws0.row(6).level = 2
ws0.row(7).level = 2
ws0.row(8).level = 1
ws0.row(9).level = 1
ws1 = wb.add_sheet('Columns Outline')
ws1.write_merge(1, 1, 1, 5, 'test 1', style)
ws1.write_merge(2, 2, 1, 4, 'test 1', style)
ws1.write_merge(3, 3, 1, 3, 'test 2', style)
ws1.write_merge(4, 4, 1, 4, 'test 1', style)
ws1.write_merge(5, 5, 1, 4, 'test 3', style)
ws1.write_merge(6, 6, 1, 5, 'test 1', style)
ws1.write_merge(7, 7, 1, 5, 'test 4', style)
ws1.write_merge(8, 8, 1, 4, 'test 1', style)
ws1.write_merge(9, 9, 1, 3, 'test 5', style)
ws1.col(1).level = 1
ws1.col(2).level = 1
ws1.col(3).level = 2
ws1.col(4).level = 2
ws1.col(5).level = 2
ws1.col(6).level = 2
ws1.col(7).level = 2
ws1.col(8).level = 1
ws1.col(9).level = 1
ws2 = wb.add_sheet('Rows and Columns Outline')
ws2.write_merge(1, 1, 1, 5, 'test 1', style)
ws2.write_merge(2, 2, 1, 4, 'test 1', style)
ws2.write_merge(3, 3, 1, 3, 'test 2', style)
ws2.write_merge(4, 4, 1, 4, 'test 1', style)
ws2.write_merge(5, 5, 1, 4, 'test 3', style)
ws2.write_merge(6, 6, 1, 5, 'test 1', style)
ws2.write_merge(7, 7, 1, 5, 'test 4', style)
ws2.write_merge(8, 8, 1, 4, 'test 1', style)
ws2.write_merge(9, 9, 1, 3, 'test 5', style)
ws2.row(1).level = 1
ws2.row(2).level = 1
ws2.row(3).level = 2
ws2.row(4).level = 2
ws2.row(5).level = 2
ws2.row(6).level = 2
ws2.row(7).level = 2
ws2.row(8).level = 1
ws2.row(9).level = 1
ws2.write_merge(1, 1, 1, 5, 'test 1', style)
ws2.write_merge(2, 2, 1, 4, 'test 1', style)
ws2.write_merge(3, 3, 1, 3, 'test 2', style)
ws2.write_merge(4, 4, 1, 4, 'test 1', style)
ws2.write_merge(5, 5, 1, 4, 'test 3', style)
ws2.write_merge(6, 6, 1, 5, 'test 1', style)
ws2.write_merge(7, 7, 1, 5, 'test 4', style)
ws2.write_merge(8, 8, 1, 4, 'test 1', style)
ws2.write_merge(9, 9, 1, 3, 'test 5', style)
ws2.col(1).level = 1
ws2.col(2).level = 1
ws2.col(3).level = 2
ws2.col(4).level = 2
ws2.col(5).level = 2
ws2.col(6).level = 2
ws2.col(7).level = 2
ws2.col(8).level = 1
ws2.col(9).level = 1
ws0.protect = True
ws0.wnd_protect = True
ws0.obj_protect = True
ws0.scen_protect = True
ws0.password = "123456"
ws1.protect = True
ws1.wnd_protect = True
ws1.obj_protect = True
ws1.scen_protect = True
ws1.password = "abcdefghij"
ws2.protect = True
ws2.wnd_protect = True
ws2.obj_protect = True
ws2.scen_protect = True
ws2.password = "ok"
wb.protect = True
wb.wnd_protect = True
wb.obj_protect = True
wb.save('protection.xls')

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,19 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: row_styles.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('Hey, Dude')
for i in range(6, 80):
fnt = Font()
fnt.height = i*20
style = XFStyle()
style.font = fnt
ws.write(i, 1, 'Test')
ws.row(i).set_style(style)
w.save('row_styles.xls')

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: row_styles_empty.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws = w.add_sheet('Hey, Dude')
for i in range(6, 80):
fnt = Font()
fnt.height = i*20
style = XFStyle()
style.font = fnt
ws.row(i).set_style(style)
w.save('row_styles_empty.xls')

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: sst.py,v 1.2 2005/03/25 07:31:12 rvk Exp $"""
from pyExcelerator import *
font0 = Formatting.Font()
font0.name = 'Arial'
font1 = Formatting.Font()
font1.name = 'Arial Cyr'
font2 = Formatting.Font()
font2.name = 'Times New Roman'
font3 = Formatting.Font()
font3.name = 'Courier New Cyr'
num_format0 = '0.00000'
num_format1 = '0.000000'
num_format2 = '0.0000000'
num_format3 = '0.00000000'
st0 = XFStyle()
st1 = XFStyle()
st2 = XFStyle()
st3 = XFStyle()
st4 = XFStyle()
st0.font = font0
st0.num_format = num_format0
st1.font = font1
st1.num_format = num_format1
st2.font = font2
st2.num_format = num_format2
st3.font = font3
st3.num_format = num_format3
wb = Workbook()
wb.add_style(st0)
wb.add_style(st1)
wb.add_style(st2)
wb.add_style(st3)
ws0 = wb.add_sheet('0')
ws0.write(0, 0, 'Olya'*0x4000, st0)
#for i in range(0, 0x10):
# ws0.write(i, 2, ('%d'%i)*0x4000, st1)
wb.save('sst.xls')

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: unicode0.py,v 1.1 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws1 = w.add_sheet('cp1251')
UnicodeUtils.DEFAULT_ENCODING = 'cp1251'
ws1.write(0, 0, 'Îëÿ')
w.save('unicode0.xls')

View File

@ -0,0 +1,30 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: unicode1.py,v 1.1 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws1 = w.add_sheet(u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK SMALL LETTER BETA}\N{GREEK SMALL LETTER GAMMA}')
ws1.write(0, 0, u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK SMALL LETTER BETA}\N{GREEK SMALL LETTER GAMMA}')
ws1.write(1, 1, u'\N{GREEK SMALL LETTER DELTA}x = 1 + \N{GREEK SMALL LETTER DELTA}')
ws1.write(2,0, u'A\u2262\u0391.') # RFC2152 example
ws1.write(3,0, u'Hi Mom -\u263a-!') # RFC2152 example
ws1.write(4,0, u'\u65E5\u672C\u8A9E') # RFC2152 example
ws1.write(5,0, u'Item 3 is \u00a31.') # RFC2152 example
ws1.write(8,0, u'\N{INTEGRAL}') # RFC2152 example
w.add_sheet(u'A\u2262\u0391.') # RFC2152 example
w.add_sheet(u'Hi Mom -\u263a-!') # RFC2152 example
one_more_ws = w.add_sheet(u'\u65E5\u672C\u8A9E') # RFC2152 example
w.add_sheet(u'Item 3 is \u00a31.') # RFC2152 example
one_more_ws.write(0, 0, u'\u2665\u2665')
w.add_sheet(u'\N{GREEK SMALL LETTER ETA WITH TONOS}')
w.save('unicode1.xls')

View File

@ -0,0 +1,21 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Kiseliov Roman
__rev_id__ = """$Id: unicode2.py,v 1.1 2005/03/27 12:47:06 rvk Exp $"""
from pyExcelerator import *
w = Workbook()
ws1 = w.add_sheet(u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK SMALL LETTER BETA}\N{GREEK SMALL LETTER GAMMA}\u2665\u041e\u041b\u042f\u2665')
fnt = Font()
fnt.height = 26*20
style = XFStyle()
style.font = fnt
for i in range(0x10000):
ws1.write(i/0x10, i%0x10, unichr(i), style)
w.save('unicode2.xls')

View File

@ -0,0 +1,157 @@
__rev_id__ = """$Id: wsprops.py,v 1.3 2005/03/27 12:47:06 rvk Exp $"""
props = \
[
'name',
'parent',
'rows',
'cols',
'merged_ranges',
'bmp_rec',
'show_formulas',
'show_grid',
'show_headers',
'panes_frozen',
'show_empty_as_zero',
'auto_colour_grid',
'cols_right_to_left',
'show_outline',
'remove_splits',
'selected',
'hidden',
'page_preview',
'first_visible_row',
'first_visible_col',
'grid_colour',
'preview_magn',
'normal_magn',
'row_gut_width',
'col_gut_height',
'show_auto_page_breaks',
'dialogue_sheet',
'auto_style_outline',
'outline_below',
'outline_right',
'fit_num_pages',
'show_row_outline',
'show_col_outline',
'alt_expr_eval',
'alt_formula_entries',
'row_default_height',
'col_default_width',
'calc_mode',
'calc_count',
'RC_ref_mode',
'iterations_on',
'delta',
'save_recalc',
'print_headers',
'print_grid',
'grid_set',
'vert_page_breaks',
'horz_page_breaks',
'header_str',
'footer_str',
'print_centered_vert',
'print_centered_horz',
'left_margin',
'right_margin',
'top_margin',
'bottom_margin',
'paper_size_code',
'print_scaling',
'start_page_number',
'fit_width_to_pages',
'fit_height_to_pages',
'print_in_rows',
'portrait',
'print_not_colour',
'print_draft',
'print_notes',
'print_notes_at_end',
'print_omit_errors',
'print_hres',
'print_vres',
'header_margin',
'footer_margin',
'copies_num',
]
from pyExcelerator import *
wb = Workbook()
ws = wb.add_sheet('sheet')
print ws.name
print ws.parent
print ws.rows
print ws.cols
print ws.merged_ranges
print ws.bmp_rec
print ws.show_formulas
print ws.show_grid
print ws.show_headers
print ws.panes_frozen
print ws.show_empty_as_zero
print ws.auto_colour_grid
print ws.cols_right_to_left
print ws.show_outline
print ws.remove_splits
print ws.selected
print ws.hidden
print ws.page_preview
print ws.first_visible_row
print ws.first_visible_col
print ws.grid_colour
print ws.preview_magn
print ws.normal_magn
#print ws.row_gut_width
#print ws.col_gut_height
print ws.show_auto_page_breaks
print ws.dialogue_sheet
print ws.auto_style_outline
print ws.outline_below
print ws.outline_right
print ws.fit_num_pages
print ws.show_row_outline
print ws.show_col_outline
print ws.alt_expr_eval
print ws.alt_formula_entries
print ws.row_default_height
print ws.col_default_width
print ws.calc_mode
print ws.calc_count
print ws.RC_ref_mode
print ws.iterations_on
print ws.delta
print ws.save_recalc
print ws.print_headers
print ws.print_grid
#print ws.grid_set
print ws.vert_page_breaks
print ws.horz_page_breaks
print ws.header_str
print ws.footer_str
print ws.print_centered_vert
print ws.print_centered_horz
print ws.left_margin
print ws.right_margin
print ws.top_margin
print ws.bottom_margin
print ws.paper_size_code
print ws.print_scaling
print ws.start_page_number
print ws.fit_width_to_pages
print ws.fit_height_to_pages
print ws.print_in_rows
print ws.portrait
print ws.print_colour
print ws.print_draft
print ws.print_notes
print ws.print_notes_at_end
print ws.print_omit_errors
print ws.print_hres
print ws.print_vres
print ws.header_margin
print ws.footer_margin
print ws.copies_num

View File

@ -0,0 +1,3 @@
/py-2.4-hrc.py/1.1/Tue Jul 19 18:58:44 2005//
/python.hrc/1.2/Tue Jul 19 18:58:44 2005//
D

View File

@ -0,0 +1,2 @@
/py-2.4-hrc.py////*///
/python.hrc////*///

View File

@ -0,0 +1,2 @@
/py-2.4-hrc.py////*///
/python.hrc////*///

View File

@ -0,0 +1,3 @@
/py-2.4-hrc.py/1.1/Thu Mar 24 15:30:01 2005//
/python.hrc/1.2/Sun Mar 27 12:47:06 2005//
D

View File

@ -0,0 +1 @@
pyExcelerator/hrc

View File

@ -0,0 +1 @@
:ext:rvk@cvs.sf.net:/cvsroot/pyexcelerator

View File

@ -0,0 +1,312 @@
specials = [
"Ellipsis",
"False",
"None",
"NotImplemented",
"True",
"__abs__",
"__add__",
"__and__",
"__base__",
"__bases__",
"__basicsize__",
"__builtins__",
"__call__",
"__class__",
"__cmp__",
"__coerce__",
"__contains__",
"__debug__",
"__del__",
"__delattr__",
"__delete__",
"__delitem__",
"__delslice__",
"__dict__",
"__dictoffset__",
"__div__",
"__divmod__",
"__doc__",
"__eq__",
"__flags__",
"__float__",
"__floordiv__",
"__ge__",
"__get__",
"__getattr__",
"__getattribute__",
"__getitem__",
"__getnewargs__",
"__getslice__",
"__gt__",
"__hash__",
"__hex__",
"__iadd__",
"__iand__",
"__idiv__",
"__ifloordiv__",
"__ilshift__",
"__imod__",
"__import__",
"__imul__",
"__init__",
"__int__",
"__invert__",
"__ior__",
"__ipow__",
"__irshift__",
"__isub__",
"__itemsize__",
"__iter__",
"__itruediv__",
"__ixor__",
"__le__",
"__len__",
"__long__",
"__lshift__",
"__lt__",
"__main__",
"__mod__",
"__module__",
"__mro__",
"__mul__",
"__name__",
"__ne__",
"__neg__",
"__new__",
"__nonzero__",
"__oct__",
"__or__",
"__pos__",
"__pow__",
"__radd__",
"__rand__",
"__rdiv__",
"__rdivmod__",
"__reduce__",
"__reduce_ex__",
"__repr__",
"__rfloordiv__",
"__rlshift__",
"__rmod__",
"__rmul__",
"__ror__",
"__rpow__",
"__rrshift__",
"__rshift__",
"__rsub__",
"__rtruediv__",
"__rxor__",
"__set__",
"__setattr__",
"__setitem__",
"__setslice__",
"__str__",
"__sub__",
"__truediv__",
"__weakrefoffset__",
"__xor__",
"abs",
"apply",
"basestring",
"bool",
"buffer",
"callable",
"capitalize",
"center",
"chr",
"classmethod",
"cmp",
"coerce",
"compile",
"complex",
"count",
"decode",
"delattr",
"dict",
"dir",
"divmod",
"encode",
"endswith",
"enumerate",
"eval",
"execfile",
"exit",
"expandtabs",
"file",
"filter",
"find",
"float",
"frozenset",
"getattr",
"globals",
"hasattr",
"hash",
"hex",
"id",
"index",
"input",
"int",
"intern",
"isalnum",
"isalpha",
"isdigit",
"isinstance",
"islower",
"isspace",
"issubclass",
"istitle",
"isupper",
"iter",
"join",
"len",
"list",
"ljust",
"locals",
"long",
"lower",
"lstrip",
"map",
"max",
"min",
"next",
"object",
"oct",
"open",
"ord",
"pow",
"property",
"quit",
"range",
"raw_input",
"reduce",
"reload",
"replace",
"repr",
"reversed",
"rfind",
"rindex",
"rjust",
"round",
"rsplit",
"rstrip",
"set",
"setattr",
"slice",
"sorted",
"split",
"splitlines",
"startswith",
"staticmethod",
"str",
"strip",
"sum",
"super",
"swapcase",
"title",
"translate",
"tuple",
"type",
"unichr",
"unicode",
"upper",
"vars",
"xrange",
"zfill",
"zip"
]
exceptions = [
"Exception",
"SystemExit",
"StopIteration",
"StandardError",
"KeyboardInterrupt",
"ImportError",
"EnvironmentError",
"IOError",
"OSError",
"WindowsError",
"EOFError",
"RuntimeError",
"NotImplementedError",
"NameError",
"UnboundLocalError",
"AttributeError",
"SyntaxError",
"IndentationError",
"TabError",
"TypeError",
"AssertionError",
"LookupError",
"IndexError",
"KeyError",
"ArithmeticError",
"OverflowError",
"ZeroDivisionError",
"FloatingPointError",
"ValueError",
"UnicodeError",
"UnicodeEncodeError",
"UnicodeDecodeError",
"UnicodeTranslateError",
"ReferenceError",
"SystemError",
"MemoryError",
"Warning",
"UserWarning",
"DeprecationWarning",
"PendingDeprecationWarning",
"SyntaxWarning",
"OverflowWarning", # not generated in 2.4; won't exist in 2.5
"RuntimeWarning",
"FutureWarning"
]
reserved_words = [
"and",
"del",
"for",
"is",
"raise",
"assert",
"elif",
"from" ,
"lambda",
"return",
"break",
"else",
"global",
"not",
"try",
"class",
"except",
"if",
"or",
"while",
"continue",
"exec",
"import",
"pass" ,
"yield" ,
"def",
"finally",
"in",
"print"
]
print '<keywords region="pyWord">'
for word in sorted(reserved_words):
print ' <word name="%s"/>' % word
print '</keywords>'
print '<keywords region="pyException">'
for exc in sorted(exceptions):
print ' <word name="%s"/>' % exc
print '</keywords>'
print '<keywords region="pyBuiltins">'
for special in sorted(specials):
print ' <word name="%s"/>' % special
print '</keywords>'

View File

@ -0,0 +1,347 @@
<?xml version="1.0" encoding="Windows-1251"?>
<!DOCTYPE hrc SYSTEM "../hrc.dtd">
<?xml-stylesheet type="text/xsl" href="../hrc.xsl"?>
<!--
Python Defs
With help of:
Grzegorz Makarewicz <mak@mikroplan.com.pl>
-->
<!--
Updated by Roman V. Kiseliov <roman@kiseliov.ru>
for Python 2.4
-->
<hrc>
<define name="pyString" value="dString"/>
<define name="pyComment" value="dComment"/>
<define name="pySymb" value="dSymbol"/>
<define name="pyWord" value="dKeyword"/>
<define name="pyBuiltins" value="dLabel"/>
<define name="pyOctNumb" value="dNumOct"/>
<define name="pyException" value="dLabel"/>
<scheme name="python">
<regexp match="/(\#.*$)/" region0="pyComment"/>
<block start='/\"\"\"/' end='/\"\"\"/' scheme="Comment"
region="pyComment" region00="dpOpenStruct" region10="dpCloseStruct"/>
<block start="/'''/" end="/'''/" scheme="Comment"
region="pyComment" region00="dpOpenStruct" region10="dpCloseStruct"/>
<!-- Strings -->
<regexp match='/("((\\.)|[^\\"])*?")/' region0="pyString"/>
<regexp match="/('((\\.)|[^\\'])*?')/" region0="pyString"/>
<!-- Numbers -->
<inherit scheme="mFloatNumb"/>
<inherit scheme="mcHexNumb"/>
<inherit scheme="mDecNumb"/>
<regexp match="/\b(0[0-7]*[Ll]?)\B/" region0="pyOctNumb"/>
<regexp match="/(`.*`)/" region0="pyBuiltins"/>
<keywords region="pySymb">
<symb name=";"/><symb name="="/><symb name="+"/><symb name="-"/>
<symb name="/"/><symb name="*"/><symb name="&amp;"/><symb name="|"/>
<symb name="^"/><symb name="("/><symb name=")"/><symb name="["/>
<symb name="]"/><symb name=","/><symb name="."/><symb name=":"/>
<symb name="!"/><symb name="~"/><symb name="&lt;"/><symb name="&gt;"/>
<symb name="%"/><symb name="{"/><symb name="}"/><symb name="?"/>
<symb name="@"/>
</keywords>
<keywords region="pyWord">
<word name="and"/>
<word name="assert"/>
<word name="break"/>
<word name="class"/>
<word name="continue"/>
<word name="def"/>
<word name="del"/>
<word name="elif"/>
<word name="else"/>
<word name="except"/>
<word name="exec"/>
<word name="finally"/>
<word name="for"/>
<word name="from"/>
<word name="global"/>
<word name="if"/>
<word name="import"/>
<word name="in"/>
<word name="is"/>
<word name="lambda"/>
<word name="not"/>
<word name="or"/>
<word name="pass"/>
<word name="print"/>
<word name="raise"/>
<word name="return"/>
<word name="try"/>
<word name="while"/>
<word name="yield"/>
</keywords>
<keywords region="pyException">
<word name="ArithmeticError"/>
<word name="AssertionError"/>
<word name="AttributeError"/>
<word name="DeprecationWarning"/>
<word name="EOFError"/>
<word name="EnvironmentError"/>
<word name="Exception"/>
<word name="FloatingPointError"/>
<word name="FutureWarning"/>
<word name="IOError"/>
<word name="ImportError"/>
<word name="IndentationError"/>
<word name="IndexError"/>
<word name="KeyError"/>
<word name="KeyboardInterrupt"/>
<word name="LookupError"/>
<word name="MemoryError"/>
<word name="NameError"/>
<word name="NotImplementedError"/>
<word name="OSError"/>
<word name="OverflowError"/>
<word name="OverflowWarning"/>
<word name="PendingDeprecationWarning"/>
<word name="ReferenceError"/>
<word name="RuntimeError"/>
<word name="RuntimeWarning"/>
<word name="StandardError"/>
<word name="StopIteration"/>
<word name="SyntaxError"/>
<word name="SyntaxWarning"/>
<word name="SystemError"/>
<word name="SystemExit"/>
<word name="TabError"/>
<word name="TypeError"/>
<word name="UnboundLocalError"/>
<word name="UnicodeDecodeError"/>
<word name="UnicodeEncodeError"/>
<word name="UnicodeError"/>
<word name="UnicodeTranslateError"/>
<word name="UserWarning"/>
<word name="ValueError"/>
<word name="Warning"/>
<word name="WindowsError"/>
<word name="ZeroDivisionError"/>
</keywords>
<keywords region="pyBuiltins">
<word name="Ellipsis"/>
<word name="False"/>
<word name="None"/>
<word name="NotImplemented"/>
<word name="True"/>
<word name="__abs__"/>
<word name="__add__"/>
<word name="__and__"/>
<word name="__base__"/>
<word name="__bases__"/>
<word name="__basicsize__"/>
<word name="__builtins__"/>
<word name="__call__"/>
<word name="__class__"/>
<word name="__cmp__"/>
<word name="__coerce__"/>
<word name="__contains__"/>
<word name="__debug__"/>
<word name="__del__"/>
<word name="__delattr__"/>
<word name="__delete__"/>
<word name="__delitem__"/>
<word name="__delslice__"/>
<word name="__dict__"/>
<word name="__dictoffset__"/>
<word name="__div__"/>
<word name="__divmod__"/>
<word name="__doc__"/>
<word name="__eq__"/>
<word name="__flags__"/>
<word name="__float__"/>
<word name="__floordiv__"/>
<word name="__ge__"/>
<word name="__get__"/>
<word name="__getattr__"/>
<word name="__getattribute__"/>
<word name="__getitem__"/>
<word name="__getnewargs__"/>
<word name="__getslice__"/>
<word name="__gt__"/>
<word name="__hash__"/>
<word name="__hex__"/>
<word name="__iadd__"/>
<word name="__iand__"/>
<word name="__idiv__"/>
<word name="__ifloordiv__"/>
<word name="__ilshift__"/>
<word name="__imod__"/>
<word name="__import__"/>
<word name="__imul__"/>
<word name="__init__"/>
<word name="__int__"/>
<word name="__invert__"/>
<word name="__ior__"/>
<word name="__ipow__"/>
<word name="__irshift__"/>
<word name="__isub__"/>
<word name="__itemsize__"/>
<word name="__iter__"/>
<word name="__itruediv__"/>
<word name="__ixor__"/>
<word name="__le__"/>
<word name="__len__"/>
<word name="__long__"/>
<word name="__lshift__"/>
<word name="__lt__"/>
<word name="__main__"/>
<word name="__mod__"/>
<word name="__module__"/>
<word name="__mro__"/>
<word name="__mul__"/>
<word name="__name__"/>
<word name="__ne__"/>
<word name="__neg__"/>
<word name="__new__"/>
<word name="__nonzero__"/>
<word name="__oct__"/>
<word name="__or__"/>
<word name="__pos__"/>
<word name="__pow__"/>
<word name="__radd__"/>
<word name="__rand__"/>
<word name="__rdiv__"/>
<word name="__rdivmod__"/>
<word name="__reduce__"/>
<word name="__reduce_ex__"/>
<word name="__repr__"/>
<word name="__rfloordiv__"/>
<word name="__rlshift__"/>
<word name="__rmod__"/>
<word name="__rmul__"/>
<word name="__ror__"/>
<word name="__rpow__"/>
<word name="__rrshift__"/>
<word name="__rshift__"/>
<word name="__rsub__"/>
<word name="__rtruediv__"/>
<word name="__rxor__"/>
<word name="__set__"/>
<word name="__setattr__"/>
<word name="__setitem__"/>
<word name="__setslice__"/>
<word name="__str__"/>
<word name="__sub__"/>
<word name="__truediv__"/>
<word name="__weakrefoffset__"/>
<word name="__xor__"/>
<word name="abs"/>
<word name="apply"/>
<word name="basestring"/>
<word name="bool"/>
<word name="buffer"/>
<word name="callable"/>
<word name="capitalize"/>
<word name="center"/>
<word name="chr"/>
<word name="classmethod"/>
<word name="cmp"/>
<word name="coerce"/>
<word name="compile"/>
<word name="complex"/>
<word name="count"/>
<word name="decode"/>
<word name="delattr"/>
<word name="dict"/>
<word name="dir"/>
<word name="divmod"/>
<word name="encode"/>
<word name="endswith"/>
<word name="enumerate"/>
<word name="eval"/>
<word name="execfile"/>
<word name="exit"/>
<word name="expandtabs"/>
<word name="file"/>
<word name="filter"/>
<word name="find"/>
<word name="float"/>
<word name="frozenset"/>
<word name="getattr"/>
<word name="globals"/>
<word name="hasattr"/>
<word name="hash"/>
<word name="hex"/>
<word name="id"/>
<word name="index"/>
<word name="input"/>
<word name="int"/>
<word name="intern"/>
<word name="isalnum"/>
<word name="isalpha"/>
<word name="isdigit"/>
<word name="isinstance"/>
<word name="islower"/>
<word name="isspace"/>
<word name="issubclass"/>
<word name="istitle"/>
<word name="isupper"/>
<word name="iter"/>
<word name="join"/>
<word name="len"/>
<word name="list"/>
<word name="ljust"/>
<word name="locals"/>
<word name="long"/>
<word name="lower"/>
<word name="lstrip"/>
<word name="map"/>
<word name="max"/>
<word name="min"/>
<word name="next"/>
<word name="object"/>
<word name="oct"/>
<word name="open"/>
<word name="ord"/>
<word name="pow"/>
<word name="property"/>
<word name="quit"/>
<word name="range"/>
<word name="raw_input"/>
<word name="reduce"/>
<word name="reload"/>
<word name="replace"/>
<word name="repr"/>
<word name="reversed"/>
<word name="rfind"/>
<word name="rindex"/>
<word name="rjust"/>
<word name="round"/>
<word name="rsplit"/>
<word name="rstrip"/>
<word name="set"/>
<word name="setattr"/>
<word name="slice"/>
<word name="sorted"/>
<word name="split"/>
<word name="splitlines"/>
<word name="startswith"/>
<word name="staticmethod"/>
<word name="str"/>
<word name="strip"/>
<word name="sum"/>
<word name="super"/>
<word name="swapcase"/>
<word name="title"/>
<word name="translate"/>
<word name="tuple"/>
<word name="type"/>
<word name="unichr"/>
<word name="unicode"/>
<word name="upper"/>
<word name="vars"/>
<word name="xrange"/>
<word name="zfill"/>
<word name="zip"/>
</keywords>
</scheme>
</hrc>

View File

@ -0,0 +1,9 @@
/frmla.xls/1.1/Tue Aug 2 18:56:30 2005/-kb/
/chart1v8.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/excel2003.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/macro2v8.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/mini-mini.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/mini.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/oo14.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/P-0508-0000507647-3280-5298.xls/1.1/Thu Sep 29 08:49:20 2005/-kb/
D

View File

@ -0,0 +1,8 @@
/frmla.xls////*///
/chart1v8.xls////*///
/excel2003.xls////*///
/macro2v8.xls////*///
/mini-mini.xls////*///
/mini.xls////*///
/oo14.xls////*///
/P-0508-0000507647-3280-5298.xls////*///

View File

@ -0,0 +1,8 @@
/frmla.xls////*///
/chart1v8.xls////*///
/excel2003.xls////*///
/macro2v8.xls////*///
/mini-mini.xls////*///
/mini.xls////*///
/oo14.xls////*///
/P-0508-0000507647-3280-5298.xls////*///

View File

@ -0,0 +1,9 @@
/frmla.xls/1.1/Tue Aug 2 18:56:30 2005/-kb/
/chart1v8.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/excel2003.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/macro2v8.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/mini-mini.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/mini.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/oo14.xls/1.1/Tue Jul 19 18:58:44 2005/-kb/
/P-0508-0000507647-3280-5298.xls/0/dummy timestamp/-kb/
D

View File

@ -0,0 +1 @@
pyExcelerator/museum

View File

@ -0,0 +1 @@
:ext:rvk@cvs.sf.net:/cvsroot/pyexcelerator

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,305 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# Portions are Copyright (c) 2004 Evgeny Filatov <fufff@users.sourceforge.net>
# Portions are Copyright (c) 2002-2004 John McNamara (Perl Spreadsheet::WriteExcel)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
__rev_id__ = """$Id: Bitmap.py,v 1.4 2005/07/20 07:24:11 rvk Exp $"""
from BIFFRecords import BiffRecord
from struct import *
def _size_col(sheet, col):
return sheet.col_width(col)
def _size_row(sheet, row):
return sheet.row_height(row)
def _position_image(sheet, row_start, col_start, x1, y1, width, height):
"""Calculate the vertices that define the position of the image as required by
the OBJ record.
+------------+------------+
| A | B |
+-----+------------+------------+
| |(x1,y1) | |
| 1 |(A1)._______|______ |
| | | | |
| | | | |
+-----+----| BITMAP |-----+
| | | | |
| 2 | |______________. |
| | | (B2)|
| | | (x2,y2)|
+---- +------------+------------+
Example of a bitmap that covers some of the area from cell A1 to cell B2.
Based on the width and height of the bitmap we need to calculate 8 vars:
col_start, row_start, col_end, row_end, x1, y1, x2, y2.
The width and height of the cells are also variable and have to be taken into
account.
The values of col_start and row_start are passed in from the calling
function. The values of col_end and row_end are calculated by subtracting
the width and height of the bitmap from the width and height of the
underlying cells.
The vertices are expressed as a percentage of the underlying cell width as
follows (rhs values are in pixels):
x1 = X / W *1024
y1 = Y / H *256
x2 = (X-1) / W *1024
y2 = (Y-1) / H *256
Where: X is distance from the left side of the underlying cell
Y is distance from the top of the underlying cell
W is the width of the cell
H is the height of the cell
Note: the SDK incorrectly states that the height should be expressed as a
percentage of 1024.
col_start - Col containing upper left corner of object
row_start - Row containing top left corner of object
x1 - Distance to left side of object
y1 - Distance to top of object
width - Width of image frame
height - Height of image frame
"""
# Adjust start column for offsets that are greater than the col width
while x1 >= _size_col(sheet, col_start):
x1 -= _size_col(sheet, col_start)
col_start += 1
# Adjust start row for offsets that are greater than the row height
while y1 >= _size_row(sheet, row_start):
y1 -= _size_row(sheet, row_start)
row_start += 1
# Initialise end cell to the same as the start cell
row_end = row_start # Row containing bottom right corner of object
col_end = col_start # Col containing lower right corner of object
width = width + x1 - 1
height = height + y1 - 1
# Subtract the underlying cell widths to find the end cell of the image
while (width >= _size_col(sheet, col_end)):
width -= _size_col(sheet, col_end)
col_end += 1
# Subtract the underlying cell heights to find the end cell of the image
while (height >= _size_row(sheet, row_end)):
height -= _size_row(sheet, row_end)
row_end += 1
# Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell
# with zero height or width.
if ((_size_col(sheet, col_start) == 0) or (_size_col(sheet, col_end) == 0)
or (_size_row(sheet, row_start) == 0) or (_size_row(sheet, row_end) == 0)):
return
# Convert the pixel values to the percentage value expected by Excel
x1 = float(x1) / _size_col(sheet, col_start) * 1024
y1 = float(y1) / _size_row(sheet, row_start) * 256
# Distance to right side of object
x2 = float(width) / _size_col(sheet, col_end) * 1024
# Distance to bottom of object
y2 = float(height) / _size_row(sheet, row_end) * 256
return (col_start, x1, row_start, y1, col_end, x2, row_end, y2)
class ObjBmpRecord(BiffRecord):
_REC_ID = 0x005D # Record identifier
def __init__(self, row, col, sheet, im_data_bmp, x, y, scale_x, scale_y):
# Scale the frame of the image.
width = im_data_bmp.width * scale_x
height = im_data_bmp.height * scale_y
# Calculate the vertices of the image and write the OBJ record
col_start, x1, row_start, y1, col_end, x2, row_end, y2 = _position_image(sheet, row, col, x, y, width, height)
"""Store the OBJ record that precedes an IMDATA record. This could be generalise
to support other Excel objects.
"""
cObj = 0x0001 # Count of objects in file (set to 1)
OT = 0x0008 # Object type. 8 = Picture
id = 0x0001 # Object ID
grbit = 0x0614 # Option flags
colL = col_start # Col containing upper left corner of object
dxL = x1 # Distance from left side of cell
rwT = row_start # Row containing top left corner of object
dyT = y1 # Distance from top of cell
colR = col_end # Col containing lower right corner of object
dxR = x2 # Distance from right of cell
rwB = row_end # Row containing bottom right corner of object
dyB = y2 # Distance from bottom of cell
cbMacro = 0x0000 # Length of FMLA structure
Reserved1 = 0x0000 # Reserved
Reserved2 = 0x0000 # Reserved
icvBack = 0x09 # Background colour
icvFore = 0x09 # Foreground colour
fls = 0x00 # Fill pattern
fAuto = 0x00 # Automatic fill
icv = 0x08 # Line colour
lns = 0xff # Line style
lnw = 0x01 # Line weight
fAutoB = 0x00 # Automatic border
frs = 0x0000 # Frame style
cf = 0x0009 # Image format, 9 = bitmap
Reserved3 = 0x0000 # Reserved
cbPictFmla = 0x0000 # Length of FMLA structure
Reserved4 = 0x0000 # Reserved
grbit2 = 0x0001 # Option flags
Reserved5 = 0x0000 # Reserved
data = pack("<L", cObj)
data += pack("<H", OT)
data += pack("<H", id)
data += pack("<H", grbit)
data += pack("<H", colL)
data += pack("<H", dxL)
data += pack("<H", rwT)
data += pack("<H", dyT)
data += pack("<H", colR)
data += pack("<H", dxR)
data += pack("<H", rwB)
data += pack("<H", dyB)
data += pack("<H", cbMacro)
data += pack("<L", Reserved1)
data += pack("<H", Reserved2)
data += pack("<B", icvBack)
data += pack("<B", icvFore)
data += pack("<B", fls)
data += pack("<B", fAuto)
data += pack("<B", icv)
data += pack("<B", lns)
data += pack("<B", lnw)
data += pack("<B", fAutoB)
data += pack("<H", frs)
data += pack("<L", cf)
data += pack("<H", Reserved3)
data += pack("<H", cbPictFmla)
data += pack("<H", Reserved4)
data += pack("<H", grbit2)
data += pack("<L", Reserved5)
self._rec_data = data
def _process_bitmap(bitmap):
"""Convert a 24 bit bitmap into the modified internal format used by Windows.
This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the
MSDN library.
"""
# Open file and binmode the data in case the platform needs it.
fh = file(bitmap, "rb")
try:
# Slurp the file into a string.
data = fh.read()
finally:
fh.close()
# Check that the file is big enough to be a bitmap.
if len(data) <= 0x36:
raise Exception("bitmap doesn't contain enough data.")
# The first 2 bytes are used to identify the bitmap.
if (data[:2] != "BM"):
raise Exception("bitmap doesn't appear to to be a valid bitmap image.")
# Remove bitmap data: ID.
data = data[2:]
# Read and remove the bitmap size. This is more reliable than reading
# the data size at offset 0x22.
#
size = unpack("<L", data[:4])[0]
size -= 0x36 # Subtract size of bitmap header.
size += 0x0C # Add size of BIFF header.
data = data[4:]
# Remove bitmap data: reserved, offset, header length.
data = data[12:]
# Read and remove the bitmap width and height. Verify the sizes.
width, height = unpack("<LL", data[:8])
data = data[8:]
if (width > 0xFFFF):
raise Exception("bitmap: largest image width supported is 65k.")
if (height > 0xFFFF):
raise Exception("bitmap: largest image height supported is 65k.")
# Read and remove the bitmap planes and bpp data. Verify them.
planes, bitcount = unpack("<HH", data[:4])
data = data[4:]
if (bitcount != 24):
raise Exception("bitmap isn't a 24bit true color bitmap.")
if (planes != 1):
raise Exception("bitmap: only 1 plane supported in bitmap image.")
# Read and remove the bitmap compression. Verify compression.
compression = unpack("<L", data[:4])[0]
data = data[4:]
if (compression != 0):
raise Exception("bitmap: compression not supported in bitmap image.")
# Remove bitmap data: data size, hres, vres, colours, imp. colours.
data = data[20:]
# Add the BITMAPCOREHEADER data
header = pack("<LHHHH", 0x000c, width, height, 0x01, 0x18)
data = header + data
return (width, height, size, data)
class ImDataBmpRecord(BiffRecord):
_REC_ID = 0x007F
def __init__(self, filename):
"""Insert a 24bit bitmap image in a worksheet. The main record required is
IMDATA but it must be proceeded by a OBJ record to define its position.
"""
BiffRecord.__init__(self)
self.width, self.height, self.size, data = _process_bitmap(filename)
# Write the IMDATA record to store the bitmap data
cf = 0x09
env = 0x01
lcb = self.size
self._rec_data = pack("<HHL", cf, env, lcb) + data

View File

@ -0,0 +1,22 @@
/Cell.py/1.3/Thu Aug 11 08:53:48 2005//
/Row.py/1.6/Thu Aug 11 08:53:48 2005//
/__init__.py/1.6/Thu Aug 11 08:53:48 2005//
/Utils.py/1.1/Thu Aug 11 08:53:48 2005//
/Bitmap.py/1.4/Wed Jul 20 07:24:10 2005//
/Column.py/1.4/Wed Jul 20 07:24:10 2005//
/Deco.py/1.4/Wed Jul 20 07:24:10 2005//
/ExcelFormulaLexer.py/1.4/Sun Aug 14 06:40:22 2005//
/ExcelFormulaParser.py/1.4/Sun Aug 14 06:40:22 2005//
/Formatting.py/1.4/Wed Jul 20 07:24:10 2005//
/Style.py/1.4/Wed Jul 20 07:24:10 2005//
/UnicodeUtils.py/1.4/Wed Jul 20 07:24:10 2005//
/excel-formula.g/1.4/Sun Aug 14 06:40:22 2005//
/BIFFRecords.py/1.7/Wed Oct 26 07:44:24 2005//
/CompoundDoc.py/1.7/Wed Oct 26 07:44:24 2005//
/ExcelMagic.py/1.2/Wed Oct 26 07:44:24 2005//
/ImportXLS.py/1.6/Wed Oct 26 07:44:24 2005//
/Workbook.py/1.5/Wed Oct 26 07:44:24 2005//
/Worksheet.py/1.8/Wed Oct 26 07:44:24 2005//
/antlr.py/1.2/Wed Oct 26 07:44:24 2005//
/ExcelFormula.py/1.3/Thu Oct 6 17:36:56 2005//
D

View File

@ -0,0 +1,21 @@
/Cell.py////*///
/Row.py////*///
/__init__.py////*///
/Utils.py////*///
/Bitmap.py////*///
/Column.py////*///
/Deco.py////*///
/ExcelFormulaLexer.py////*///
/ExcelFormulaParser.py////*///
/Formatting.py////*///
/Style.py////*///
/UnicodeUtils.py////*///
/excel-formula.g////*///
/BIFFRecords.py////*///
/CompoundDoc.py////*///
/ExcelMagic.py////*///
/ImportXLS.py////*///
/Workbook.py////*///
/Worksheet.py////*///
/antlr.py////*///
/ExcelFormula.py////*///

View File

@ -0,0 +1,21 @@
/Cell.py////*///
/ExcelFormula.py////*///
/Row.py////*///
/__init__.py////*///
/Utils.py////*///
/Bitmap.py////*///
/Column.py////*///
/Deco.py////*///
/ExcelFormulaLexer.py////*///
/ExcelFormulaParser.py////*///
/Formatting.py////*///
/Style.py////*///
/UnicodeUtils.py////*///
/excel-formula.g////*///
/BIFFRecords.py////*///
/CompoundDoc.py////*///
/ExcelMagic.py////*///
/ImportXLS.py////*///
/Workbook.py////*///
/Worksheet.py////*///
/antlr.py////*///

View File

@ -0,0 +1,22 @@
/Cell.py/1.3/Thu Aug 11 08:53:48 2005//
/ExcelFormula.py/1.3/Thu Aug 11 08:53:48 2005//
/Row.py/1.6/Thu Aug 11 08:53:48 2005//
/__init__.py/1.6/Thu Aug 11 08:53:48 2005//
/Utils.py/1.1/Thu Aug 11 08:53:48 2005//
/Bitmap.py/1.4/Wed Jul 20 07:24:10 2005//
/Column.py/1.4/Wed Jul 20 07:24:10 2005//
/Deco.py/1.4/Wed Jul 20 07:24:10 2005//
/ExcelFormulaLexer.py/1.4/Sun Aug 14 06:40:22 2005//
/ExcelFormulaParser.py/1.4/Sun Aug 14 06:40:22 2005//
/Formatting.py/1.4/Wed Jul 20 07:24:10 2005//
/Style.py/1.4/Wed Jul 20 07:24:10 2005//
/UnicodeUtils.py/1.4/Wed Jul 20 07:24:10 2005//
/excel-formula.g/1.4/Sun Aug 14 06:40:22 2005//
/BIFFRecords.py/1.7/Wed Oct 26 07:44:24 2005//
/CompoundDoc.py/1.7/Wed Oct 26 07:44:24 2005//
/ExcelMagic.py/1.2/Wed Oct 26 07:44:24 2005//
/ImportXLS.py/1.6/Wed Oct 26 07:44:24 2005//
/Workbook.py/1.5/Wed Oct 26 07:44:24 2005//
/Worksheet.py/1.8/Wed Oct 26 07:44:24 2005//
/antlr.py/1.2/Wed Oct 26 07:44:24 2005//
D

View File

@ -0,0 +1 @@
pyExcelerator/pyExcelerator

View File

@ -0,0 +1 @@
:ext:rvk@cvs.sf.net:/cvsroot/pyexcelerator

View File

@ -0,0 +1,169 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
__rev_id__ = """$Id: Cell.py,v 1.3 2005/08/11 08:53:48 rvk Exp $"""
import struct
import BIFFRecords
class StrCell(object):
__slots__ = ["__init__", "get_biff_data",
"__parent", "__idx", "__xf_idx", "__sst_idx"]
def __init__(self, parent, idx, xf_idx, sst_idx):
self.__parent = parent
self.__idx = idx
self.__xf_idx = xf_idx
self.__sst_idx = sst_idx
def get_biff_data(self):
return BIFFRecords.LabelSSTRecord(self.__parent.get_index(), self.__idx, self.__xf_idx, self.__sst_idx).get()
class BlankCell(object):
__slots__ = ["__init__", "get_biff_data",
"__parent", "__idx", "__xf_idx"]
def __init__(self, parent, idx, xf_idx):
self.__parent = parent
self.__idx = idx
self.__xf_idx = xf_idx
def get_biff_data(self):
return BIFFRecords.BlankRecord(self.__parent.get_index(), self.__idx, self.__xf_idx).get()
class MulBlankCell(object):
__slots__ = ["__init__", "get_biff_data",
"__parent", "__col1", "__col2", "__xf_idx"]
def __init__(self, parent, col1, col2, xf_idx):
self.__parent = parent
self.__col1 = col1
self.__col2 = col2
self.__xf_idx = xf_idx
def get_biff_data(self):
return BIFFRecords.MulBlankRecord(self.__parent.get_index(), self.__col1, self.__col2, self.__xf_idx).get()
class NumberCell(object):
__slots__ = ["__init__", "get_biff_data",
"__parent", "__idx", "__xf_idx", "__number"]
def __init__(self, parent, idx, xf_idx, number):
self.__parent = parent
self.__idx = idx
self.__xf_idx = xf_idx
self.__number = float(number)
def get_biff_data(self):
rk_encoded = 0
packed = struct.pack('<d', self.__number)
#print self.__number
w0, w1, w2, w3 = struct.unpack('<4H', packed)
if w0 == 0 and w1 == 0 and w2 & 0xFFFC == w2:
# 34 lsb are 0
#print "float RK"
rk_encoded = (w3 << 16) | w2
return BIFFRecords.RKRecord(self.__parent.get_index(), self.__idx, self.__xf_idx, rk_encoded).get()
if abs(self.__number) < 0x40000000 and int(self.__number) == self.__number:
#print "30-bit integer RK"
rk_encoded = 2 | (int(self.__number) << 2)
return BIFFRecords.RKRecord(self.__parent.get_index(), self.__idx, self.__xf_idx, rk_encoded).get()
temp = self.__number*100
packed100 = struct.pack('<d', temp)
w0, w1, w2, w3 = struct.unpack('<4H', packed100)
if w0 == 0 and w1 == 0 and w2 & 0xFFFC == w2:
# 34 lsb are 0
#print "float RK*100"
rk_encoded = 1 | (w3 << 16) | w2
return BIFFRecords.RKRecord(self.__parent.get_index(), self.__idx, self.__xf_idx, rk_encoded).get()
if abs(temp) < 0x40000000 and int(temp) == temp:
#print "30-bit integer RK*100"
rk_encoded = 3 | (int(temp) << 2)
return BIFFRecords.RKRecord(self.__parent.get_index(), self.__idx, self.__xf_idx, rk_encoded).get()
#print "Number"
#print
return BIFFRecords.NumberRecord(self.__parent.get_index(), self.__idx, self.__xf_idx, self.__number).get()
class MulNumberCell(object):
__slots__ = ["__init__", "get_biff_data"]
def __init__(self, parent, idx, xf_idx, sst_idx):
self.__parent = parent
self.__idx = idx
self.__xf_idx = xf_idx
self.__sst_idx = sst_idx
def get_biff_data(self):
raise Exception
class FormulaCell(object):
__slots__ = ["__init__", "get_biff_data",
"__parent", "__idx", "__xf_idx", "__frmla"]
def __init__(self, parent, idx, xf_idx, frmla):
self.__parent = parent
self.__idx = idx
self.__xf_idx = xf_idx
self.__frmla = frmla
def get_biff_data(self):
return BIFFRecords.FormulaRecord(self.__parent.get_index(), self.__idx, self.__xf_idx, self.__frmla.rpn()).get()

View File

@ -0,0 +1,73 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
__rev_id__ = """$Id: Column.py,v 1.4 2005/07/20 07:24:11 rvk Exp $"""
from BIFFRecords import ColInfoRecord
from Deco import *
from Worksheet import Worksheet
class Column(object):
#accepts(object, int, Worksheet)
def __init__(self, indx, parent_sheet):
self._index = indx
self._parent = parent_sheet
self._parent_wb = parent_sheet.get_parent()
self._xf_index = 0x0F
self.width = 0x0B92
self.hidden = 0
self.level = 0
self.collapse = 0
def get_biff_record(self):
options = (self.hidden & 0x01) << 0
options |= (self.level & 0x07) << 8
options |= (self.collapse & 0x01) << 12
return ColInfoRecord(self._index, self._index, self.width, self._xf_index, options).get()

View File

@ -0,0 +1,577 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
import sys
import struct
__rev_id__ = """$Id: CompoundDoc.py,v 1.7 2005/10/26 07:44:24 rvk Exp $"""
class Reader:
def __init__(self, filename, dump = False, doc=None ): # XXX modif. Emmanuel
self.dump = dump
self.STREAMS = {}
if doc is None:
doc = file(filename, 'rb').read()
self.header, self.data = doc[0:512], doc[512:]
del doc
self.__build_header()
self.__build_MSAT()
self.__build_SAT()
self.__build_directory()
self.__build_short_sectors_data()
if len(self.short_sectors_data) > 0:
self.__build_SSAT()
else:
if self.dump and (self.total_ssat_sectors != 0 or self.ssat_start_sid != -2):
print 'NOTE: header says that must be', self.total_ssat_sectors, 'short sectors'
print 'NOTE: starting at', self.ssat_start_sid, 'sector'
print 'NOTE: but file does not contains data in short sectors'
self.ssat_start_sid = -2
self.total_ssat_sectors = 0
self.SSAT = [-2]
for dentry in self.dir_entry_list[1:]:
(did,
sz, name,
t, c,
did_left, did_right, did_root,
dentry_start_sid,
stream_size
) = dentry
stream_data = ''
if stream_size > 0:
if stream_size >= self.min_stream_size:
args = (self.data, self.SAT, dentry_start_sid, self.sect_size)
else:
args = (self.short_sectors_data, self.SSAT, dentry_start_sid, self.short_sect_size)
stream_data = self.get_stream_data(*args)
if name != '':
# BAD IDEA: names may be equal. NEED use full paths...
self.STREAMS[name] = stream_data
def __build_header(self):
self.doc_magic = self.header[0:8]
if self.doc_magic != '\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1':
raise Exception, 'Not an OLE file.'
self.file_uid = self.header[8:24]
self.rev_num = self.header[24:26]
self.ver_num = self.header[26:28]
self.byte_order = self.header[28:30]
self.log2_sect_size, = struct.unpack('<H', self.header[30:32])
self.log2_short_sect_size, = struct.unpack('<H', self.header[32:34])
self.total_sat_sectors, = struct.unpack('<L', self.header[44:48])
self.dir_start_sid, = struct.unpack('<l', self.header[48:52])
self.min_stream_size, = struct.unpack('<L', self.header[56:60])
self.ssat_start_sid, = struct.unpack('<l', self.header[60:64])
self.total_ssat_sectors, = struct.unpack('<L', self.header[64:68])
self.msat_start_sid, = struct.unpack('<l', self.header[68:72])
self.total_msat_sectors, = struct.unpack('<L', self.header[72:76])
self.sect_size = 1 << self.log2_sect_size
self.short_sect_size = 1 << self.log2_short_sect_size
if self.dump:
print 'file magic: '
print_bin_data(self.doc_magic)
print 'file uid: '
print_bin_data(self.file_uid)
print 'revision number: '
print_bin_data(self.rev_num)
print 'version number: '
print_bin_data(self.ver_num)
print 'byte order: '
print_bin_data(self.byte_order)
print 'sector size :', hex(self.sect_size), self.sect_size
#print 'total sectors in file :', hex(self.total_sectors), self.total_sectors
print 'short sector size :', hex(self.short_sect_size), self.short_sect_size
print 'Total number of sectors used for the SAT :', hex(self.total_sat_sectors), self.total_sat_sectors
print 'SID of first sector of the directory stream:', hex(self.dir_start_sid), self.dir_start_sid
print 'Minimum size of a standard stream :', hex(self.min_stream_size), self.min_stream_size
print 'SID of first sector of the SSAT :', hex(self.ssat_start_sid), self.ssat_start_sid
print 'Total number of sectors used for the SSAT :', hex(self.total_ssat_sectors), self.total_ssat_sectors
print 'SID of first additional sector of the MSAT :', hex(self.msat_start_sid), self.msat_start_sid
print 'Total number of sectors used for the MSAT :', hex(self.total_msat_sectors), self.total_msat_sectors
def __build_MSAT(self):
self.MSAT = list(struct.unpack('<109l', self.header[76:]))
next = self.msat_start_sid
while next > 0:
msat_sector = struct.unpack('<128l', self.data[next*self.sect_size:(next+1)*self.sect_size])
self.MSAT.extend(msat_sector[:127])
next = msat_sector[-1]
if self.dump:
print 'MSAT (header part): \n', self.MSAT[:109]
print 'additional MSAT sectors: \n', self.MSAT[109:]
def __build_SAT(self):
sat_stream = ''.join([self.data[i*self.sect_size:(i+1)*self.sect_size] for i in self.MSAT if i >= 0])
sat_sids_count = len(sat_stream) >> 2
self.SAT = struct.unpack('<%dl' % sat_sids_count, sat_stream) # SIDs tuple
if self.dump:
print 'SAT sid count:\n', sat_sids_count
print 'SAT content:\n', self.SAT
def __build_SSAT(self):
ssat_stream = self.get_stream_data(self.data, self.SAT, self.ssat_start_sid, self.sect_size)
ssids_count = len(ssat_stream) >> 2
self.SSAT = struct.unpack('<%dl' % ssids_count, ssat_stream)
if self.dump:
print 'SSID count:', ssids_count
print 'SSAT content:\n', self.SSAT
def __build_directory(self):
dir_stream = self.get_stream_data(self.data, self.SAT, self.dir_start_sid, self.sect_size)
self.dir_entry_list = []
i = 0
while i < len(dir_stream):
dentry = dir_stream[i:i+128] # 128 -- dir entry size
i += 128
did = len(self.dir_entry_list)
sz, = struct.unpack('<H', dentry[64:66])
if sz > 0 :
name = dentry[0:sz-2].decode('utf_16_le', 'replace')
else:
name = u''
t, = struct.unpack('B', dentry[66])
c, = struct.unpack('B', dentry[67])
did_left , = struct.unpack('<l', dentry[68:72])
did_right , = struct.unpack('<l', dentry[72:76])
did_root , = struct.unpack('<l', dentry[76:80])
dentry_start_sid , = struct.unpack('<l', dentry[116:120])
stream_size , = struct.unpack('<L', dentry[120:124])
self.dir_entry_list.extend([(did, sz, name, t, c,
did_left, did_right, did_root,
dentry_start_sid, stream_size)])
if self.dump:
dentry_types = {
0x00: 'Empty',
0x01: 'User storage',
0x02: 'User stream',
0x03: 'LockBytes',
0x04: 'Property',
0x05: 'Root storage'
}
node_colours = {
0x00: 'Red',
0x01: 'Black'
}
print 'total directory entries:', len(self.dir_entry_list)
for dentry in self.dir_entry_list:
(did, sz, name, t, c,
did_left, did_right, did_root,
dentry_start_sid, stream_size) = dentry
print 'DID', did
print 'Size of the used area of the character buffer of the name:', sz
print 'dir entry name:', repr(name)
print 'type of entry:', t, dentry_types[t]
print 'entry colour:', c, node_colours[c]
print 'left child DID :', did_left
print 'right child DID:', did_right
print 'root DID :', did_root
print 'start SID :', dentry_start_sid
print 'stream size :', stream_size
if stream_size == 0:
print 'stream is empty'
elif stream_size >= self.min_stream_size:
print 'stream stored as normal stream'
else:
print 'stream stored as short-stream'
def __build_short_sectors_data(self):
(did, sz, name, t, c,
did_left, did_right, did_root,
dentry_start_sid, stream_size) = self.dir_entry_list[0]
assert t == 0x05 # Short-Stream Container Stream (SSCS) resides in Root Storage
if stream_size == 0:
self.short_sectors_data = ''
else:
self.short_sectors_data = self.get_stream_data(self.data, self.SAT, dentry_start_sid, self.sect_size)
def get_stream_data(self, data, SAT, start_sid, sect_size):
sid = start_sid
chunks = [(sid, sid)]
stream_data = ''
while SAT[sid] >= 0:
next_in_chain = SAT[sid]
last_chunk_start, last_chunk_finish = chunks[-1]
if next_in_chain - last_chunk_finish <= 1:
chunks[-1] = last_chunk_start, next_in_chain
else:
chunks.extend([(next_in_chain, next_in_chain)])
sid = next_in_chain
for s, f in chunks:
stream_data += data[s*sect_size:(f+1)*sect_size]
#print chunks
return stream_data
def print_bin_data(data):
i = 0
while i < len(data):
j = 0
while (i < len(data)) and (j < 16):
c = '0x%02X' % ord(data[i])
sys.stdout.write(c)
sys.stdout.write(' ')
i += 1
j += 1
print
if i == 0:
print '<NO DATA>'
# This implementation writes only 'Root Entry', 'Workbook' streams
# and 2 empty streams for aligning directory stream on sector boundary
#
# LAYOUT:
# 0 header
# 76 MSAT (1st part: 109 SID)
# 512 workbook stream
# ... additional MSAT sectors if streams' size > about 7 Mb == (109*512 * 128)
# ... SAT
# ... directory stream
#
# NOTE: this layout is "ad hoc". It can be more general. RTFM
class XlsDoc:
SECTOR_SIZE = 0x0200
MIN_LIMIT = 0x1000
SID_FREE_SECTOR = -1
SID_END_OF_CHAIN = -2
SID_USED_BY_SAT = -3
SID_USED_BY_MSAT = -4
def __init__(self):
#self.book_stream = '' # padded
self.book_stream_sect = []
self.dir_stream = ''
self.dir_stream_sect = []
self.packed_SAT = ''
self.SAT_sect = []
self.packed_MSAT_1st = ''
self.packed_MSAT_2nd = ''
self.MSAT_sect_2nd = []
self.header = ''
def __build_directory(self): # align on sector boundary
self.dir_stream = ''
dentry_name = '\x00'.join('Root Entry\x00') + '\x00'
dentry_name_sz = len(dentry_name)
dentry_name_pad = '\x00'*(64 - dentry_name_sz)
dentry_type = 0x05 # root storage
dentry_colour = 0x01 # black
dentry_did_left = -1
dentry_did_right = -1
dentry_did_root = 1
dentry_start_sid = -2
dentry_stream_sz = 0
self.dir_stream += struct.pack('<64s H 2B 3l 9L l L L',
dentry_name + dentry_name_pad,
dentry_name_sz,
dentry_type,
dentry_colour,
dentry_did_left,
dentry_did_right,
dentry_did_root,
0, 0, 0, 0, 0, 0, 0, 0, 0,
dentry_start_sid,
dentry_stream_sz,
0
)
dentry_name = '\x00'.join('Workbook\x00') + '\x00'
dentry_name_sz = len(dentry_name)
dentry_name_pad = '\x00'*(64 - dentry_name_sz)
dentry_type = 0x02 # user stream
dentry_colour = 0x01 # black
dentry_did_left = -1
dentry_did_right = -1
dentry_did_root = -1
dentry_start_sid = 0
dentry_stream_sz = self.book_stream_len
self.dir_stream += struct.pack('<64s H 2B 3l 9L l L L',
dentry_name + dentry_name_pad,
dentry_name_sz,
dentry_type,
dentry_colour,
dentry_did_left,
dentry_did_right,
dentry_did_root,
0, 0, 0, 0, 0, 0, 0, 0, 0,
dentry_start_sid,
dentry_stream_sz,
0
)
# padding
dentry_name = ''
dentry_name_sz = len(dentry_name)
dentry_name_pad = '\x00'*(64 - dentry_name_sz)
dentry_type = 0x00 # empty
dentry_colour = 0x01 # black
dentry_did_left = -1
dentry_did_right = -1
dentry_did_root = -1
dentry_start_sid = -2
dentry_stream_sz = 0
self.dir_stream += struct.pack('<64s H 2B 3l 9L l L L',
dentry_name + dentry_name_pad,
dentry_name_sz,
dentry_type,
dentry_colour,
dentry_did_left,
dentry_did_right,
dentry_did_root,
0, 0, 0, 0, 0, 0, 0, 0, 0,
dentry_start_sid,
dentry_stream_sz,
0
) * 2
def __build_sat(self):
# Build SAT
book_sect_count = self.book_stream_len >> 9
dir_sect_count = len(self.dir_stream) >> 9
total_sect_count = book_sect_count + dir_sect_count
SAT_sect_count = 0
MSAT_sect_count = 0
SAT_sect_count_limit = 109
while total_sect_count > 128*SAT_sect_count or SAT_sect_count > SAT_sect_count_limit:
SAT_sect_count += 1
total_sect_count += 1
if SAT_sect_count > SAT_sect_count_limit:
MSAT_sect_count += 1
total_sect_count += 1
SAT_sect_count_limit += 127
SAT = [self.SID_FREE_SECTOR]*128*SAT_sect_count
sect = 0
while sect < book_sect_count - 1:
self.book_stream_sect.append(sect)
SAT[sect] = sect + 1
sect += 1
self.book_stream_sect.append(sect)
SAT[sect] = self.SID_END_OF_CHAIN
sect += 1
while sect < book_sect_count + MSAT_sect_count:
self.MSAT_sect_2nd.append(sect)
SAT[sect] = self.SID_USED_BY_MSAT
sect += 1
while sect < book_sect_count + MSAT_sect_count + SAT_sect_count:
self.SAT_sect.append(sect)
SAT[sect] = self.SID_USED_BY_SAT
sect += 1
while sect < book_sect_count + MSAT_sect_count + SAT_sect_count + dir_sect_count - 1:
self.dir_stream_sect.append(sect)
SAT[sect] = sect + 1
sect += 1
self.dir_stream_sect.append(sect)
SAT[sect] = self.SID_END_OF_CHAIN
sect += 1
self.packed_SAT = struct.pack('<%dl' % (SAT_sect_count*128), *SAT)
MSAT_1st = [self.SID_FREE_SECTOR]*109
for i, SAT_sect_num in zip(range(0, 109), self.SAT_sect):
MSAT_1st[i] = SAT_sect_num
self.packed_MSAT_1st = struct.pack('<109l', *MSAT_1st)
MSAT_2nd = [self.SID_FREE_SECTOR]*128*MSAT_sect_count
if MSAT_sect_count > 0:
MSAT_2nd[- 1] = self.SID_END_OF_CHAIN
i = 109
msat_sect = 0
sid_num = 0
while i < SAT_sect_count:
if (sid_num + 1) % 128 == 0:
#print 'link: ',
msat_sect += 1
if msat_sect < len(self.MSAT_sect_2nd):
MSAT_2nd[sid_num] = self.MSAT_sect_2nd[msat_sect]
else:
#print 'sid: ',
MSAT_2nd[sid_num] = self.SAT_sect[i]
i += 1
#print sid_num, MSAT_2nd[sid_num]
sid_num += 1
self.packed_MSAT_2nd = struct.pack('<%dl' % (MSAT_sect_count*128), *MSAT_2nd)
#print vars()
#print zip(range(0, sect), SAT)
#print self.book_stream_sect
#print self.MSAT_sect_2nd
#print MSAT_2nd
#print self.SAT_sect
#print self.dir_stream_sect
def __build_header(self):
doc_magic = '\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1'
file_uid = '\x00'*16
rev_num = '\x3E\x00'
ver_num = '\x03\x00'
byte_order = '\xFE\xFF'
log_sect_size = struct.pack('<H', 9)
log_short_sect_size = struct.pack('<H', 6)
not_used0 = '\x00'*10
total_sat_sectors = struct.pack('<L', len(self.SAT_sect))
dir_start_sid = struct.pack('<l', self.dir_stream_sect[0])
not_used1 = '\x00'*4
min_stream_size = struct.pack('<L', 0x1000)
ssat_start_sid = struct.pack('<l', -2)
total_ssat_sectors = struct.pack('<L', 0)
if len(self.MSAT_sect_2nd) == 0:
msat_start_sid = struct.pack('<l', -2)
else:
msat_start_sid = struct.pack('<l', self.MSAT_sect_2nd[0])
total_msat_sectors = struct.pack('<L', len(self.MSAT_sect_2nd))
self.header = ''.join([ doc_magic,
file_uid,
rev_num,
ver_num,
byte_order,
log_sect_size,
log_short_sect_size,
not_used0,
total_sat_sectors,
dir_start_sid,
not_used1,
min_stream_size,
ssat_start_sid,
total_ssat_sectors,
msat_start_sid,
total_msat_sectors
])
def save(self, filename, stream):
# 1. Align stream on 0x1000 boundary (and therefore on sector boundary)
padding = '\x00' * (0x1000 - (len(stream) % 0x1000))
self.book_stream_len = len(stream) + len(padding)
self.__build_directory()
self.__build_sat()
self.__build_header()
f = file(filename, 'wb')
f.write(self.header)
f.write(self.packed_MSAT_1st)
f.write(stream)
f.write(padding)
f.write(self.packed_MSAT_2nd)
f.write(self.packed_SAT)
f.write(self.dir_stream)
f.close()
def savetostr(self, stream): # XXX added by Emmanuel
# 1. Align stream on 0x1000 boundary (and therefore on sector boundary)
padding = '\x00' * (0x1000 - (len(stream) % 0x1000))
self.book_stream_len = len(stream) + len(padding)
self.__build_directory()
self.__build_sat()
self.__build_header()
return self.header+self.packed_MSAT_1st+stream+padding+self.packed_MSAT_2nd+self.packed_SAT+self.dir_stream
if __name__ == '__main__':
d = XlsDoc()
d.save('a.aaa', 'b'*17000)

View File

@ -0,0 +1,61 @@
# This code from
# PEP: 318
# Title: Decorators for Functions and Methods
# Version: 1.35
# Last-Modified: 2004/09/14 07:34:23
# Author: Kevin D. Smith, Jim Jewett, Skip Montanaro, Anthony Baxter
# This code fixes error in example 4:
# authors' code contains
# @accepts(int, (int,float))
# @returns((int,float))
# def func(arg1, arg2):
# return arg1 * arg2
#
# It should be:
# @returns((int,float))
# @accepts(int, (int,float))
# def func(arg1, arg2):
# return arg1 * arg2
# because of decorators are applied from bottom to up.
__rev_id__ = """$Id: Deco.py,v 1.4 2005/07/20 07:24:11 rvk Exp $"""
def accepts(*types):
#print types
def check_accepts(f):
assert len(types) == f.func_code.co_argcount
def new_f(*args, **kwds):
for (a, t) in zip(args, types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)
return f(*args, **kwds)
new_f.func_name = f.func_name
return new_f
return check_accepts
def returns(rtype):
def check_returns(f):
def new_f(*args, **kwds):
result = f(*args, **kwds)
assert isinstance(result, rtype), \
"return value %r does not match %s" % (result,rtype)
return result
new_f.func_name = f.func_name
return new_f
return check_returns
if __name__ == '__main__':
import types
## @returns(types.NoneType)
## @accepts(int, (int,float))
def func(arg1, arg2):
#return str(arg1 * arg2)
pass
func(1, 2)

View File

@ -0,0 +1,76 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
__rev_id__ = """$Id: ExcelFormula.py,v 1.3 2005/08/11 08:53:48 rvk Exp $"""
import ExcelFormulaParser, ExcelFormulaLexer
import struct
from antlr import ANTLRException
class Formula(object):
__slots__ = ["__init__", "text", "rpn", "__s", "__parser"]
def __init__(self, s):
try:
self.__s = s
lexer = ExcelFormulaLexer.Lexer(s)
self.__parser = ExcelFormulaParser.Parser(lexer)
self.__parser.formula()
except ANTLRException:
raise Exception, "can't parse formula " + s
def text(self):
return self.__s
def rpn(self):
'''
Offset Size Contents
0 2 Size of the following formula data (sz)
2 sz Formula data (RPN token array)
[2+sz] var. (optional) Additional data for specific tokens
'''
return struct.pack("<H", len(self.__parser.rpn)) + self.__parser.rpn

View File

@ -0,0 +1,158 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
__rev_id__ = """$Id: ExcelFormulaLexer.py,v 1.4 2005/08/14 06:40:23 rvk Exp $"""
import sys
from antlr import EOF, CommonToken as Tok, TokenStream, TokenStreamException
import struct
import ExcelFormulaParser
from re import compile as recompile, match, LOCALE, UNICODE, IGNORECASE
int_const_pattern = recompile(r"\d+")
flt_const_pattern = recompile(r"\d*\.\d+(?:[Ee][+-]?\d+)?")
str_const_pattern = recompile(r'["][^"]*["]')
#range2d_pattern = recompile(r"\$?[A-I]?[A-Z]\$?\d+:\$?[A-I]?[A-Z]\$?\d+")
ref2d_pattern = recompile(r"\$?[A-I]?[A-Z]\$?\d+")
true_pattern = recompile(r"TRUE", IGNORECASE)
false_pattern = recompile(r"FALSE", IGNORECASE)
name_pattern = recompile(r"[\.\w]+", LOCALE)
pattern_type_tuples = (
(flt_const_pattern, ExcelFormulaParser.NUM_CONST),
(int_const_pattern, ExcelFormulaParser.INT_CONST),
(str_const_pattern, ExcelFormulaParser.STR_CONST),
# (range2d_pattern , ExcelFormulaParser.RANGE2D),
(ref2d_pattern , ExcelFormulaParser.REF2D),
(true_pattern , ExcelFormulaParser.TRUE_CONST),
(false_pattern , ExcelFormulaParser.FALSE_CONST),
(name_pattern , ExcelFormulaParser.NAME)
)
type_text_tuples = (
(ExcelFormulaParser.NE, '<>'),
(ExcelFormulaParser.LE, '<='),
(ExcelFormulaParser.GE, '>='),
(ExcelFormulaParser.EQ, '='),
(ExcelFormulaParser.LT, '<'),
(ExcelFormulaParser.GT, '>'),
(ExcelFormulaParser.ADD, '+'),
(ExcelFormulaParser.SUB, '-'),
(ExcelFormulaParser.MUL, '*'),
(ExcelFormulaParser.DIV, '/'),
(ExcelFormulaParser.COLON, ':'),
(ExcelFormulaParser.SEMICOLON, ';'),
(ExcelFormulaParser.COMMA, ','),
(ExcelFormulaParser.LP, '('),
(ExcelFormulaParser.RP, ')'),
(ExcelFormulaParser.CONCAT, '&'),
(ExcelFormulaParser.PERCENT, '%'),
(ExcelFormulaParser.POWER, '^')
)
class Lexer(TokenStream):
def __init__(self, text):
self._text = text[:]
self._pos = 0
self._line = 0
def isEOF(self):
return len(self._text) <= self._pos
def curr_ch(self):
return self._text[self._pos]
def next_ch(self, n = 1):
self._pos += n
def is_whitespace(self):
return self.curr_ch() in " \t\n\r\f\v"
def match_pattern(self, pattern, toktype):
m = pattern.match(self._text[self._pos:])
if m:
start_pos = self._pos + m.start(0)
end_pos = self._pos + m.end(0)
tt = self._text[start_pos:end_pos]
self._pos = end_pos
return Tok(type = toktype, text = tt, col = start_pos + 1)
else:
return None
def nextToken(self):
# skip whitespace
while not self.isEOF() and self.is_whitespace():
self.next_ch()
if self.isEOF():
return Tok(type = EOF)
# first, try to match token with more chars
for ptt in pattern_type_tuples:
t = self.match_pattern(*ptt);
if t:
return t
# second, we want find short tokens
for ty, te in type_text_tuples:
if self.curr_ch() == te:
self.next_ch()
return Tok(type = ty, text = te, col = self._pos)
# at this point, smth strange is happened
raise TokenStreamException("Unknown char %s at %u col." % (self.curr_ch(), self._pos))
if __name__ == '__main__' :
import locale
locale.setlocale(locale.LC_ALL, 'russian')
try:
for t in Lexer('1+2+3+67.8678 + " @##$$$ klhkh kljhklhkl " + .58e-678*A1:B4 - 1lkjljlkjl3535ïîðïîð'):
print t
except TokenStreamException, e:
print "error:", e

View File

@ -0,0 +1,457 @@
### $ANTLR 2.7.5 (20050128): "excel-formula.g" -> "ExcelFormulaParser.py"$
### import antlr and other modules ..
import sys
import antlr
version = sys.version.split()[0]
if version < '2.2.1':
False = 0
if version < '2.3':
True = not False
### header action >>>
__rev_id__ = """$Id: ExcelFormulaParser.py,v 1.4 2005/08/14 06:40:23 rvk Exp $"""
import struct
import Utils
from UnicodeUtils import upack1
from ExcelMagic import *
### header action <<<
### preamble action>>>
### preamble action <<<
### import antlr.Token
from antlr import Token
### >>>The Known Token Types <<<
SKIP = antlr.SKIP
INVALID_TYPE = antlr.INVALID_TYPE
EOF_TYPE = antlr.EOF_TYPE
EOF = antlr.EOF
NULL_TREE_LOOKAHEAD = antlr.NULL_TREE_LOOKAHEAD
MIN_USER_TYPE = antlr.MIN_USER_TYPE
TRUE_CONST = 4
FALSE_CONST = 5
STR_CONST = 6
NUM_CONST = 7
INT_CONST = 8
NAME = 9
EQ = 10
NE = 11
GT = 12
LT = 13
GE = 14
LE = 15
ADD = 16
SUB = 17
MUL = 18
DIV = 19
POWER = 20
PERCENT = 21
LP = 22
RP = 23
LB = 24
RB = 25
COLON = 26
COMMA = 27
SEMICOLON = 28
CONCAT = 29
REF2D = 30
class Parser(antlr.LLkParser):
### user action >>>
### user action <<<
def __init__(self, *args, **kwargs):
antlr.LLkParser.__init__(self, *args, **kwargs)
self.tokenNames = _tokenNames
### __init__ header action >>>
self.rpn = ""
### __init__ header action <<<
def formula(self):
pass
self.expr("V")
def expr(self,
arg_type
):
pass
self.prec0_expr(arg_type)
while True:
if ((self.LA(1) >= EQ and self.LA(1) <= LE)):
pass
la1 = self.LA(1)
if False:
pass
elif la1 and la1 in [EQ]:
pass
self.match(EQ)
op = struct.pack('B', ptgEQ)
elif la1 and la1 in [NE]:
pass
self.match(NE)
op = struct.pack('B', ptgNE)
elif la1 and la1 in [GT]:
pass
self.match(GT)
op = struct.pack('B', ptgGE)
elif la1 and la1 in [LT]:
pass
self.match(LT)
op = struct.pack('B', ptgLT)
elif la1 and la1 in [GE]:
pass
self.match(GE)
op = struct.pack('B', ptgGE)
elif la1 and la1 in [LE]:
pass
self.match(LE)
op = struct.pack('B', ptgLE)
else:
raise antlr.NoViableAltException(self.LT(1), self.getFilename())
self.prec0_expr(arg_type)
self.rpn += op
else:
break
def prec0_expr(self,
arg_type
):
pass
self.prec1_expr(arg_type)
while True:
if (self.LA(1)==CONCAT):
pass
pass
self.match(CONCAT)
op = struct.pack('B', ptgConcat)
self.prec1_expr(arg_type)
self.rpn += op
else:
break
def prec1_expr(self,
arg_type
):
pass
self.prec2_expr(arg_type)
while True:
if (self.LA(1)==ADD or self.LA(1)==SUB):
pass
la1 = self.LA(1)
if False:
pass
elif la1 and la1 in [ADD]:
pass
self.match(ADD)
op = struct.pack('B', ptgAdd)
elif la1 and la1 in [SUB]:
pass
self.match(SUB)
op = struct.pack('B', ptgSub)
else:
raise antlr.NoViableAltException(self.LT(1), self.getFilename())
self.prec2_expr(arg_type)
self.rpn += op
else:
break
def prec2_expr(self,
arg_type
):
pass
self.prec3_expr(arg_type)
while True:
if (self.LA(1)==MUL or self.LA(1)==DIV):
pass
la1 = self.LA(1)
if False:
pass
elif la1 and la1 in [MUL]:
pass
self.match(MUL)
op = struct.pack('B', ptgMul)
elif la1 and la1 in [DIV]:
pass
self.match(DIV)
op = struct.pack('B', ptgDiv)
else:
raise antlr.NoViableAltException(self.LT(1), self.getFilename())
self.prec3_expr(arg_type)
self.rpn += op
else:
break
def prec3_expr(self,
arg_type
):
pass
self.prec4_expr(arg_type)
while True:
if (self.LA(1)==POWER):
pass
pass
self.match(POWER)
op = struct.pack('B', ptgPower)
self.prec4_expr(arg_type)
self.rpn += op
else:
break
def prec4_expr(self,
arg_type
):
pass
self.prec5_expr(arg_type)
la1 = self.LA(1)
if False:
pass
elif la1 and la1 in [PERCENT]:
pass
self.match(PERCENT)
self.rpn += struct.pack('B', ptgPercent)
elif la1 and la1 in [EOF,EQ,NE,GT,LT,GE,LE,ADD,SUB,MUL,DIV,POWER,RP,SEMICOLON,CONCAT]:
pass
else:
raise antlr.NoViableAltException(self.LT(1), self.getFilename())
def prec5_expr(self,
arg_type
):
la1 = self.LA(1)
if False:
pass
elif la1 and la1 in [TRUE_CONST,FALSE_CONST,STR_CONST,NUM_CONST,INT_CONST,NAME,LP,REF2D]:
pass
self.primary(arg_type)
elif la1 and la1 in [SUB]:
pass
self.match(SUB)
self.primary(arg_type)
self.rpn += struct.pack('B', ptgUminus)
else:
raise antlr.NoViableAltException(self.LT(1), self.getFilename())
def primary(self,
arg_type
):
str_tok = None
int_tok = None
num_tok = None
ref2d_tok = None
ref2d1_tok = None
ref2d2_tok = None
name_tok = None
func_tok = None
la1 = self.LA(1)
if False:
pass
elif la1 and la1 in [TRUE_CONST]:
pass
self.match(TRUE_CONST)
self.rpn += struct.pack("2B", ptgBool, 1)
elif la1 and la1 in [FALSE_CONST]:
pass
self.match(FALSE_CONST)
self.rpn += struct.pack("2B", ptgBool, 0)
elif la1 and la1 in [STR_CONST]:
pass
str_tok = self.LT(1)
self.match(STR_CONST)
self.rpn += struct.pack("B", ptgStr) + upack1(str_tok.text[1:-1])
elif la1 and la1 in [INT_CONST]:
pass
int_tok = self.LT(1)
self.match(INT_CONST)
self.rpn += struct.pack("<BH", ptgInt, int(int_tok.text))
elif la1 and la1 in [NUM_CONST]:
pass
num_tok = self.LT(1)
self.match(NUM_CONST)
self.rpn += struct.pack("<Bd", ptgNum, float(num_tok.text))
elif la1 and la1 in [LP]:
pass
self.match(LP)
self.expr(arg_type)
self.match(RP)
self.rpn += struct.pack("B", ptgParen)
else:
if (self.LA(1)==REF2D) and (_tokenSet_0.member(self.LA(2))):
pass
ref2d_tok = self.LT(1)
self.match(REF2D)
r, c = Utils.cell_to_packed_rowcol(ref2d_tok.text)
if arg_type == "R":
self.rpn += struct.pack("<B2H", ptgRefR, r, c)
else:
self.rpn += struct.pack("<B2H", ptgRefV, r, c)
elif (self.LA(1)==REF2D) and (self.LA(2)==COLON):
pass
ref2d1_tok = self.LT(1)
self.match(REF2D)
self.match(COLON)
ref2d2_tok = self.LT(1)
self.match(REF2D)
r1, c1 = Utils.cell_to_packed_rowcol(ref2d1_tok.text)
r2, c2 = Utils.cell_to_packed_rowcol(ref2d2_tok.text)
if arg_type == "R":
self.rpn += struct.pack("<B4H", ptgAreaR, r1, r2, c1, c2)
else:
self.rpn += struct.pack("<B4H", ptgAreaV, r1, r2, c1, c2)
elif (self.LA(1)==NAME) and (_tokenSet_0.member(self.LA(2))):
pass
name_tok = self.LT(1)
self.match(NAME)
self.rpn += ""
elif (self.LA(1)==NAME) and (self.LA(2)==LP):
pass
func_tok = self.LT(1)
self.match(NAME)
if func_tok.text.upper() in std_func_by_name:
(opcode,
min_argc,
max_argc,
func_type,
arg_type_list,
volatile_func) = std_func_by_name[func_tok.text.upper()]
else:
raise Exception, "unknown function: %s" % func_tok.text
self.match(LP)
arg_count=self.expr_list(arg_type_list, min_argc, max_argc)
self.match(RP)
if arg_count > max_argc or arg_count < min_argc:
raise Exception, "%d parameters for function: %s" % (arg_count, func_tok.text)
if min_argc == max_argc:
if func_type == "V":
func_ptg = ptgFuncV
elif func_type == "R":
func_ptg = ptgFuncR
elif func_type == "A":
func_ptg = ptgFuncA
else:
raise Exception, "wrong function type"
self.rpn += struct.pack("<BH", func_ptg, opcode)
else:
if func_type == "V":
func_ptg = ptgFuncVarV
elif func_type == "R":
func_ptg = ptgFuncVarR
elif func_type == "A":
func_ptg = ptgFuncVarA
else:
raise Exception, "wrong function type"
self.rpn += struct.pack("<2BH", func_ptg, arg_count, opcode)
else:
raise antlr.NoViableAltException(self.LT(1), self.getFilename())
def expr_list(self,
arg_type_list, min_argc, max_argc
):
arg_cnt = None
arg_cnt = 0
arg_type_list = arg_type_list.split()
arg_type = arg_type_list[arg_cnt]
la1 = self.LA(1)
if False:
pass
elif la1 and la1 in [TRUE_CONST,FALSE_CONST,STR_CONST,NUM_CONST,INT_CONST,NAME,SUB,LP,REF2D]:
pass
self.expr(arg_type)
arg_cnt += 1
while True:
if (self.LA(1)==SEMICOLON):
pass
if arg_cnt < len(arg_type_list):
arg_type = arg_type_list[arg_cnt]
else:
arg_type = arg_type_list[-1]
if arg_type == "...":
arg_type = arg_type_list[-2]
self.match(SEMICOLON)
la1 = self.LA(1)
if False:
pass
elif la1 and la1 in [TRUE_CONST,FALSE_CONST,STR_CONST,NUM_CONST,INT_CONST,NAME,SUB,LP,REF2D]:
pass
self.expr(arg_type)
elif la1 and la1 in [RP,SEMICOLON]:
pass
self.rpn += struct.pack("B", ptgMissArg)
else:
raise antlr.NoViableAltException(self.LT(1), self.getFilename())
arg_cnt += 1
else:
break
elif la1 and la1 in [RP]:
pass
else:
raise antlr.NoViableAltException(self.LT(1), self.getFilename())
return arg_cnt
_tokenNames = [
"<0>",
"EOF",
"<2>",
"NULL_TREE_LOOKAHEAD",
"TRUE_CONST",
"FALSE_CONST",
"STR_CONST",
"NUM_CONST",
"INT_CONST",
"NAME",
"EQ",
"NE",
"GT",
"LT",
"GE",
"LE",
"ADD",
"SUB",
"MUL",
"DIV",
"POWER",
"PERCENT",
"LP",
"RP",
"LB",
"RB",
"COLON",
"COMMA",
"SEMICOLON",
"CONCAT",
"REF2D"
]
### generate bit set
def mk_tokenSet_0():
### var1
data = [ 817888258L, 0L]
return data
_tokenSet_0 = antlr.BitSet(mk_tokenSet_0())

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,278 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
'''
The XF record is able to store explicit cell formatting attributes or the
attributes of a cell style. Explicit formatting includes the reference to
a cell style XF record. This allows to extend a defined cell style with
some explicit attributes. The formatting attributes are divided into
6 groups:
Group Attributes
-------------------------------------
Number format Number format index (index to FORMAT record)
Font Font index (index to FONT record)
Alignment Horizontal and vertical alignment, text wrap, indentation,
orientation/rotation, text direction
Border Border line styles and colours
Background Background area style and colours
Protection Cell locked, formula hidden
For each group a flag in the cell XF record specifies whether to use the
attributes contained in that XF record or in the referenced style
XF record. In style XF records, these flags specify whether the attributes
will overwrite explicit cell formatting when the style is applied to
a cell. Changing a cell style (without applying this style to a cell) will
change all cells which already use that style and do not contain explicit
cell attributes for the changed style attributes. If a cell XF record does
not contain explicit attributes in a group (if the attribute group flag
is not set), it repeats the attributes of its style XF record.
'''
__rev_id__ = """$Id: Formatting.py,v 1.4 2005/07/20 07:24:11 rvk Exp $"""
import BIFFRecords
class Font(object):
ESCAPEMENT_NONE = 0x00
ESCAPEMENT_SUPERSCRIPT = 0x01
ESCAPEMENT_SUBSCRIPT = 0x02
UNDERLINE_NONE = 0x00
UNDERLINE_SINGLE = 0x01
UNDERLINE_SINGLE_ACC = 0x21
UNDERLINE_DOUBLE = 0x02
UNDERLINE_DOUBLE_ACC = 0x22
FAMILY_NONE = 0x00
FAMILY_ROMAN = 0x01
FAMILY_SWISS = 0x02
FAMILY_MODERN = 0x03
FAMILY_SCRIPT = 0x04
FAMILY_DECORARTIVE = 0x05
CHARSET_ANSI_LATIN = 0x00
CHARSET_SYS_DEFAULT = 0x01
CHARSET_SYMBOL = 0x02
CHARSET_APPLE_ROMAN = 0x4D
CHARSET_ANSI_JAP_SHIFT_JIS = 0x80
CHARSET_ANSI_KOR_HANGUL = 0x81
CHARSET_ANSI_KOR_JOHAB = 0x82
CHARSET_ANSI_CHINESE_GBK = 0x86
CHARSET_ANSI_CHINESE_BIG5 = 0x88
CHARSET_ANSI_GREEK = 0xA1
CHARSET_ANSI_TURKISH = 0xA2
CHARSET_ANSI_VIETNAMESE = 0xA3
CHARSET_ANSI_HEBREW = 0xB1
CHARSET_ANSI_ARABIC = 0xB2
CHARSET_ANSI_BALTIC = 0xBA
CHARSET_ANSI_CYRILLIC = 0xCC
CHARSET_ANSI_THAI = 0xDE
CHARSET_ANSI_LATIN_II = 0xEE
CHARSET_OEM_LATIN_I = 0xFF
def __init__(self):
# twip = 1/20 of a point = 1/1440 of a inch
# usually resolution == 96 pixels per 1 inch
# (rarely 120 pixels per 1 inch or another one)
self.height = 0x00C8 # 200: this is font with height 10 points
self.italic = False
self.struck_out = False
self.outline = False
self.shadow = False
self.colour_index = 0x7FFF
self.bold = False
self._weight = 0x0190 # 0x02BC gives bold font
self.escapement = self.ESCAPEMENT_NONE
self.underline = self.UNDERLINE_NONE
self.family = self.FAMILY_NONE
self.charset = self.CHARSET_ANSI_CYRILLIC
self.name = 'Arial'
def get_biff_record(self):
height = self.height
options = 0x00
if self.bold:
options |= 0x01
self._weight = 0x02BC
if self.italic:
options |= 0x02
if self.underline != self.UNDERLINE_NONE:
options |= 0x04
if self.struck_out:
options |= 0x08
if self.outline:
options |= 0x010
if self.shadow:
options |= 0x020
colour_index = self.colour_index
weight = self._weight
escapement = self.escapement
underline = self.underline
family = self.family
charset = self.charset
name = self.name
return BIFFRecords.FontRecord(height, options, colour_index, weight, escapement,
underline, family, charset,
name)
class Alignment(object):
HORZ_GENERAL = 0x00
HORZ_LEFT = 0x01
HORZ_CENTER = 0x02
HORZ_RIGHT = 0x03
HORZ_FILLED = 0x04
HORZ_JUSTIFIED = 0x05 # BIFF4-BIFF8X
HORZ_CENTER_ACROSS_SEL = 0x06 # Centred across selection (BIFF4-BIFF8X)
HORZ_DISTRIBUTED = 0x07 # Distributed (BIFF8X)
VERT_TOP = 0x00
VERT_CENTER = 0x01
VERT_BOTTOM = 0x02
VERT_JUSTIFIED = 0x03 # Justified (BIFF5-BIFF8X)
VERT_DISIRIBUTED = 0x04 # Distributed (BIFF8X)
DIRECTION_GENERAL = 0x00 # BIFF8X
DIRECTION_LR = 0x01
DIRECTION_RL = 0x02
ORIENTATION_NOT_ROTATED = 0x00
ORIENTATION_STACKED = 0x01
ORIENTATION_90_CC = 0x02
ORIENTATION_90_CW = 0x03
ROTATION_0_ANGLE = 0x00
ROTATION_STACKED = 0xFF
WRAP_AT_RIGHT = 0x01
NOT_WRAP_AT_RIGHT = 0x00
SHRINK_TO_FIT = 0x01
NOT_SHRINK_TO_FIT = 0x00
def __init__(self):
self.horz = self.HORZ_GENERAL
self.vert = self.VERT_BOTTOM
self.dire = self.DIRECTION_GENERAL
self.orie = self.ORIENTATION_NOT_ROTATED
self.rota = self.ROTATION_0_ANGLE
self.wrap = self.NOT_WRAP_AT_RIGHT
self.shri = self.NOT_SHRINK_TO_FIT
self.inde = 0
self.merg = 0
class Borders(object):
NO_LINE = 0x00
THIN = 0x01
MEDIUM = 0x02
DASHED = 0x03
DOTTED = 0x04
THICK = 0x05
DOUBLE = 0x06
HAIR = 0x07
#The following for BIFF8
MEDIUM_DASHED = 0x08
THIN_DASH_DOTTED = 0x09
MEDIUM_DASH_DOTTED = 0x0A
THIN_DASH_DOT_DOTTED = 0x0B
MEDIUM_DASH_DOT_DOTTED = 0x0C
SLANTED_MEDIUM_DASH_DOTTED = 0x0D
NEED_DIAG1 = 0x01
NEED_DIAG2 = 0x01
NO_NEED_DIAG1 = 0x00
NO_NEED_DIAG2 = 0x00
def __init__(self):
self.left = self.NO_LINE
self.right = self.NO_LINE
self.top = self.NO_LINE
self.bottom = self.NO_LINE
self.diag = self.NO_LINE
self.left_colour = 0x40
self.right_colour = 0x40
self.top_colour = 0x40
self.bottom_colour = 0x40
self.diag_colour = 0x40
self.need_diag1 = self.NO_NEED_DIAG1
self.need_diag2 = self.NO_NEED_DIAG2
class Pattern(object):
# patterns 0x00 - 0x12
NO_PATTERN = 0x00
SOLID_PATTERN = 0x01
def __init__(self):
self.pattern = self.NO_PATTERN
self.pattern_fore_colour = 0x40
self.pattern_back_colour = 0x41
class Protection(object):
def __init__(self):
self.cell_locked = 1
self.formula_hidden = 0
if __name__ == '__main__':
font0 = Font()
font0.name = 'Arial'
font1 = Font()
font1.name = 'Arial Cyr'
font2 = Font()
font2.name = 'Times New Roman'
font3 = Font()
font3.name = 'Courier New Cyr'
for font, filename in [(font0, 'font0.bin'), (font1, 'font1.bin'), (font2, 'font2.bin'), (font3, 'font3.bin')]:
f = file(filename, 'wb')
f.write(font.get_biff_record().get_data())
f.close

View File

@ -0,0 +1,476 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
__rev_id__ = """$Id: ImportXLS.py,v 1.6 2005/10/26 07:44:24 rvk Exp $"""
import UnicodeUtils
import CompoundDoc
import ExcelMagic
from struct import pack, unpack
def parse_xls(filename, encoding = None, doc=None): # XXX added doc arg.
##########################################################################
def process_BOUNDSHEET(biff8, rec_data):
sheet_stream_pos, visibility, sheet_type = unpack('<I2B', rec_data[:6])
sheet_name = rec_data[6:]
if biff8:
chars_num, options = unpack('2B', sheet_name[:2])
chars_start = 2
runs_num = 0
asian_phonetic_size = 0
result = ''
compressed = (options & 0x01) == 0
has_asian_phonetic = (options & 0x04) != 0
has_format_runs = (options & 0x08) != 0
if has_format_runs:
runs_num , = unpack('<H', sheet_name[chars_start:chars_start+2])
chars_start += 2
if has_asian_phonetic:
asian_phonetic_size , = unpack('<I', sheet_name[chars_start:chars_start+4])
chars_start += 4
if compressed:
chars_end = chars_start + chars_num
result = sheet_name[chars_start:chars_end].decode('latin_1', 'replace')
else:
chars_end = chars_start + 2*chars_num
result = sheet_name[chars_start:chars_end].decode('utf_16_le', 'replace')
tail_size = 4*runs_num + asian_phonetic_size
else:
result = sheet_name[1:].decode(encoding, 'replace')
return result
def unpack2str(biff8, label_name): # 2 bytes length str
if biff8:
chars_num, options = unpack('<HB', label_name[:3])
chars_start = 3
runs_num = 0
asian_phonetic_size = 0
result = ''
compressed = (options & 0x01) == 0
has_asian_phonetic = (options & 0x04) != 0
has_format_runs = (options & 0x08) != 0
if has_format_runs:
runs_num , = unpack('<H', label_name[chars_start:chars_start+2])
chars_start += 2
if has_asian_phonetic:
asian_phonetic_size , = unpack('<I', label_name[chars_start:chars_start+4])
chars_start += 4
if compressed:
chars_end = chars_start + chars_num
result = label_name[chars_start:chars_end].decode('latin_1', 'replace')
else:
chars_end = chars_start + 2*chars_num
result = label_name[chars_start:chars_end].decode('utf_16_le', 'replace')
tail_size = 4*runs_num + asian_phonetic_size
else:
result = label_name[2:].decode(encoding, 'replace')
return result
def process_LABEL(biff8, rec_data):
row_idx, col_idx, xf_idx = unpack('<3H', rec_data[:6])
label_name = rec_data[6:]
result = unpack2str(biff8, label_name)
return (row_idx, col_idx, result)
def process_LABELSST(rec_data):
row_idx, col_idx, xf_idx, sst_idx = unpack('<3HI', rec_data)
return (row_idx, col_idx, sst_idx)
def process_RSTRING(biff8, rec_data):
if biff8:
return process_LABEL(biff8, rec_data)
else:
row_idx, col_idx, xf_idx, length = unpack('<4H', rec_data[:8])
result = rec_data[8:8+length].decode(encoding, 'replace')
return (row_idx, col_idx, result)
def decode_rk(encoded):
b0, b1, b2, b3 = unpack('4B', encoded)
is_multed_100 = (b0 & 0x01) != 0
is_integer = (b0 & 0x02) != 0
if is_integer:
result , = unpack('<i', encoded)
result >>= 2
else:
ieee754 = struct.pack('8B', 0, 0, 0, 0, b0 & 0xFC, b1, b2, b3)
result , = unpack('<d', ieee754)
if is_multed_100:
result /= 100.0
return result
def process_RK(rec_data):
row_idx, col_idx, xf_idx, encoded = unpack('<3H4s', rec_data)
result = decode_rk(encoded)
return (row_idx, col_idx, result)
def process_MULRK(rec_data):
row_idx, first_col_idx = unpack('<2H', rec_data[:4])
last_col_idx , = unpack('<H', rec_data[-2:])
xf_rk_num = last_col_idx - first_col_idx + 1
results = []
for i in range(xf_rk_num):
xf_idx, encoded = unpack('<H4s', rec_data[4+6*i : 4+6*(i+1)])
results.append(decode_rk(encoded))
return zip([row_idx]*xf_rk_num, range(first_col_idx, last_col_idx+1), results)
def process_NUMBER(rec_data):
row_idx, col_idx, xf_idx, result = unpack('<3Hd', rec_data)
return (row_idx, col_idx, result)
def process_SST(rec_data, sst_continues):
# 0x00FC
total_refs, total_str = unpack('<2I', rec_data[:8])
#print total_refs, str_num
pos = 8
curr_block = rec_data
curr_block_num = -1
curr_str_num = 0
SST = {}
while curr_str_num < total_str:
if pos >= len(curr_block):
curr_block_num += 1
curr_block = sst_continues[curr_block_num]
pos = 0
chars_num, options = unpack('<HB', curr_block[pos:pos+3])
#print chars_num, options
pos += 3
asian_phonetic_size = 0
runs_num = 0
has_asian_phonetic = (options & 0x04) != 0
has_format_runs = (options & 0x08) != 0
if has_format_runs:
runs_num , = unpack('<H', curr_block[pos:pos+2])
pos += 2
if has_asian_phonetic:
asian_phonetic_size , = unpack('<I', curr_block[pos:pos+4])
pos += 4
curr_char = 0
result = ''
while curr_char < chars_num:
if pos >= len(curr_block):
curr_block_num += 1
curr_block = sst_continues[curr_block_num]
options = ord(curr_block[0])
pos = 1
#print curr_block_num
compressed = (options & 0x01) == 0
if compressed:
chars_end = pos + chars_num - curr_char
else:
chars_end = pos + 2*(chars_num - curr_char)
#print compressed, has_asian_phonetic, has_format_runs
splitted = chars_end > len(curr_block)
if splitted:
chars_end = len(curr_block)
#print splitted, curr_char, pos, chars_end, repr(curr_block[pos:chars_end])
if compressed:
result += curr_block[pos:chars_end].decode('latin_1', 'replace')
else:
result += curr_block[pos:chars_end].decode('utf_16_le', 'replace')
pos = chars_end
curr_char = len(result)
# end while
# TODO: handle spanning format runs over CONTINUE blocks ???
tail_size = 4*runs_num + asian_phonetic_size
if len(curr_block) < pos + tail_size:
pos = pos + tail_size - len(curr_block)
curr_block_num += 1
curr_block = sst_continues[curr_block_num]
else:
pos += tail_size
#print result.encode('cp866')
SST[curr_str_num] = result
curr_str_num += 1
return SST
#####################################################################################
import struct
encodings = {
0x016F: 'ascii', #ASCII
0x01B5: 'cp437', #IBM PC CP-437 (US)
0x02D0: 'cp720', #IBM PC CP-720 (OEM Arabic)
0x02E1: 'cp737', #IBM PC CP-737 (Greek)
0x0307: 'cp775', #IBM PC CP-775 (Baltic)
0x0352: 'cp850', #IBM PC CP-850 (Latin I)
0x0354: 'cp852', #IBM PC CP-852 (Latin II (Central European))
0x0357: 'cp855', #IBM PC CP-855 (Cyrillic)
0x0359: 'cp857', #IBM PC CP-857 (Turkish)
0x035A: 'cp858', #IBM PC CP-858 (Multilingual Latin I with Euro)
0x035C: 'cp860', #IBM PC CP-860 (Portuguese)
0x035D: 'cp861', #IBM PC CP-861 (Icelandic)
0x035E: 'cp862', #IBM PC CP-862 (Hebrew)
0x035F: 'cp863', #IBM PC CP-863 (Canadian (French))
0x0360: 'cp864', #IBM PC CP-864 (Arabic)
0x0361: 'cp865', #IBM PC CP-865 (Nordic)
0x0362: 'cp866', #IBM PC CP-866 (Cyrillic (Russian))
0x0365: 'cp869', #IBM PC CP-869 (Greek (Modern))
0x036A: 'cp874', #Windows CP-874 (Thai)
0x03A4: 'cp932', #Windows CP-932 (Japanese Shift-JIS)
0x03A8: 'cp936', #Windows CP-936 (Chinese Simplified GBK)
0x03B5: 'cp949', #Windows CP-949 (Korean (Wansung))
0x03B6: 'cp950', #Windows CP-950 (Chinese Traditional BIG5)
0x04B0: 'utf_16_le', #UTF-16 (BIFF8)
0x04E2: 'cp1250', #Windows CP-1250 (Latin II) (Central European)
0x04E3: 'cp1251', #Windows CP-1251 (Cyrillic)
0x04E4: 'cp1252', #Windows CP-1252 (Latin I) (BIFF4-BIFF7)
0x04E5: 'cp1253', #Windows CP-1253 (Greek)
0x04E6: 'cp1254', #Windows CP-1254 (Turkish)
0x04E7: 'cp1255', #Windows CP-1255 (Hebrew)
0x04E8: 'cp1256', #Windows CP-1256 (Arabic)
0x04E9: 'cp1257', #Windows CP-1257 (Baltic)
0x04EA: 'cp1258', #Windows CP-1258 (Vietnamese)
0x0551: 'cp1361', #Windows CP-1361 (Korean (Johab))
0x2710: 'mac_roman', #Apple Roman
0x8000: 'mac_roman', #Apple Roman
0x8001: 'cp1252' #Windows CP-1252 (Latin I) (BIFF2-BIFF3)
}
biff8 = True
SST = {}
sheets = []
sheet_names = []
values = {}
ws_num = 0
BOFs = 0
EOFs = 0
# Inside MS Office document looks like filesystem
# We need extract stream named 'Workbook' or 'Book'
ole_streams = CompoundDoc.Reader(filename, doc=doc).STREAMS
if 'Workbook' in ole_streams:
workbook_stream = ole_streams['Workbook']
elif 'Book' in ole_streams:
workbook_stream = ole_streams['Book']
else:
raise Exception, 'No workbook stream in file.'
workbook_stream_len = len(workbook_stream)
stream_pos = 0
# Excel's method of data storing is based on
# ancient technology "TLV" (Type, Length, Value).
# In addition, if record size grows to some limit
# Excel writes CONTINUE records
while stream_pos < workbook_stream_len and EOFs <= ws_num:
rec_id, data_size = unpack('<2H', workbook_stream[stream_pos:stream_pos+4])
stream_pos += 4
rec_data = workbook_stream[stream_pos:stream_pos+data_size]
stream_pos += data_size
if rec_id == 0x0809: # BOF
#print 'BOF',
BOFs += 1
ver, substream_type = unpack('<2H', rec_data[:4])
if substream_type == 0x0005:
# workbook global substream
biff8 = ver >= 0x0600
elif substream_type == 0x0010:
# worksheet substream
pass
else: # skip chart stream or unknown stream
# stream offsets may be used from BOUNDSHEET record
rec_id, data_size = unpack('<2H', workbook_stream[stream_pos:stream_pos+4])
while rec_id != 0x000A: # EOF
#print 'SST CONTINUE'
stream_pos += 4
stream_pos += data_size
rec_id, data_size = unpack('<2H', workbook_stream[stream_pos:stream_pos+4])
#print 'BIFF8 == ', biff8
elif rec_id == 0x000A: # EOF
#print 'EOF'
if BOFs > 1:
sheets.extend([values])
values = {}
EOFs += 1
elif rec_id == 0x0042: # CODEPAGE
cp , = unpack('<H', rec_data)
#print 'CODEPAGE', hex(cp)
if not encoding:
encoding = encodings[cp]
#print encoding
elif rec_id == 0x0085: # BOUNDSHEET
#print 'BOUNDSHEET',
ws_num += 1
b = process_BOUNDSHEET(biff8, rec_data)
sheet_names.extend([b])
#print b.encode('cp866')
elif rec_id == 0x00FC: # SST
#print 'SST'
sst_data = rec_data
sst_continues = []
rec_id, data_size = unpack('<2H', workbook_stream[stream_pos:stream_pos+4])
while rec_id == 0x003C: # CONTINUE
#print 'SST CONTINUE'
stream_pos += 4
rec_data = workbook_stream[stream_pos:stream_pos+data_size]
sst_continues.extend([rec_data])
stream_pos += data_size
rec_id, data_size = unpack('<2H', workbook_stream[stream_pos:stream_pos+4])
SST = process_SST(sst_data, sst_continues)
elif rec_id == 0x00FD: # LABELSST
#print 'LABELSST',
r, c, i = process_LABELSST(rec_data)
values[(r, c)] = SST[i]
#print r, c, SST[i].encode('cp866')
elif rec_id == 0x0204: # LABEL
#print 'LABEL',
r, c, b = process_LABEL(biff8, rec_data)
values[(r, c)] = b
#print r, c, b.encode('cp866')
elif rec_id == 0x00D6: # RSTRING
#print 'RSTRING',
r, c, b = process_RSTRING(biff8, rec_data)
values[(r, c)] = b
#print r, c, b.encode('cp866')
elif rec_id == 0x027E: # RK
#print 'RK',
r, c, b = process_RK(rec_data)
values[(r, c)] = b
#print r, c, b
elif rec_id == 0x00BD: # MULRK
#print 'MULRK',
for r, c, b in process_MULRK(rec_data):
values[(r, c)] = b
#print r, c, b
elif rec_id == 0x0203: # NUMBER
#print 'NUMBER',
r, c, b = process_NUMBER(rec_data)
values[(r, c)] = b
#print r, c, b
elif rec_id == 0x0006: # FORMULA
#print 'FORMULA',
r, c, x = unpack('<3H', rec_data[0:6])
if rec_data[12] == '\xFF' and rec_data[13] == '\xFF':
if rec_data[6] == '\x00':
got_str = False
if ord(rec_data[14]) & 8:
# part of shared formula
rec_id, data_size = unpack('<2H', workbook_stream[stream_pos:stream_pos+4])
stream_pos += 4
rec_data = workbook_stream[stream_pos:stream_pos+data_size]
stream_pos += data_size
if rec_id == 0x0207: # STRING
got_str = True
elif rec_id not in (0x0221, 0x04BC, 0x0236, 0x0037, 0x0036):
raise Exception("Expected ARRAY, SHRFMLA, TABLEOP* or STRING record")
if not got_str:
rec_id, data_size = unpack('<2H', workbook_stream[stream_pos:stream_pos+4])
stream_pos += 4
rec_data = workbook_stream[stream_pos:stream_pos+data_size]
stream_pos += data_size
if rec_id != 0x0207: # STRING
raise Exception("Expected STRING record")
values[(r, c)] = unpack2str(biff8, rec_data)
elif rec_data[6] == '\x01':
# boolean
v = ord(rec_data[8])
values[(r, c)] = bool(v)
elif rec_data[6] == '\x02':
# error
v = ord(rec_data[8])
if v in ExcelMagic.error_msg_by_code:
values[(r, c)] = ExcelMagic.error_msg_by_code[v]
else:
values[(r, c)] = u'#UNKNOWN ERROR!'
elif rec_data[6] == '\x03':
# empty
values[(r, c)] = u''
else:
raise Exception("Unknown value for formula result")
else:
# 64-bit float
d, = unpack("<d", rec_data[6:14])
values[(r, c)] = d
encoding = None
return zip(sheet_names, sheets)

View File

@ -0,0 +1,231 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
__rev_id__ = """$Id: Row.py,v 1.6 2005/08/11 08:53:48 rvk Exp $"""
import BIFFRecords
from Deco import *
from Worksheet import Worksheet
import Style
import Cell
import ExcelFormula
import datetime as dt
class Row(object):
__slots__ = ["__init__",
"__adjust_height",
"__adjust_bound_col_idx",
"__excel_date_dt",
"get_height_in_pixels",
"set_style",
"get_xf_index",
"get_cells_count",
"get_min_col",
"get_max_col",
"get_str_count",
"get_row_biff_data",
"get_cells_biff_data",
"get_index",
"write",
"write_blanks",
# private variables
"__idx",
"__parent",
"__parent_wb",
"__cells",
"__min_col_idx",
"__max_col_idx",
"__total_str",
"__xf_index",
"__has_default_format",
"__height_in_pixels",
# public variables
"height",
"has_default_height",
"level",
"collapse",
"hidden",
"space_above",
"space_below"]
#################################################################
## Constructor
#################################################################
def __init__(self, index, parent_sheet):
self.__idx = index
self.__parent = parent_sheet
self.__parent_wb = parent_sheet.get_parent()
self.__cells = []
self.__min_col_idx = 0
self.__max_col_idx = 0
self.__total_str = 0
self.__xf_index = 0x0F
self.__has_default_format = 0
self.__height_in_pixels = 0x11
self.height = 0x00FF
self.has_default_height = 0x00
self.level = 0
self.collapse = 0
self.hidden = 0
self.space_above = 0
self.space_below = 0
def __adjust_height(self, style):
twips = style.font.height
points = float(twips)/20.0
# Cell height in pixels can be calcuted by following approx. formula:
# cell height in pixels = font height in points * 83/50 + 2/5
# It works when screen resolution is 96 dpi
pix = int(round(points*83.0/50.0 + 2.0/5.0))
if pix > self.__height_in_pixels:
self.__height_in_pixels = pix
def __adjust_bound_col_idx(self, *args):
for arg in args:
if arg < self.__min_col_idx:
self.__min_col_idx = arg
elif arg > self.__max_col_idx:
self.__max_col_idx = arg
def __excel_date_dt(self, date):
if isinstance(date, dt.date) and (not isinstance(date, dt.datetime)):
epoch = dt.date(1899, 12, 31)
elif isinstance(date, dt.time):
date = dt.datetime.combine(dt.datetime(1900, 1, 1), date)
epoch = dt.datetime(1900, 1, 1, 0, 0, 0)
else:
epoch = dt.datetime(1899, 12, 31, 0, 0, 0)
delta = date - epoch
xldate = delta.days + float(delta.seconds) / (24*60*60)
# Add a day for Excel's missing leap day in 1900
if xldate > 59:
xldate += 1
return xldate
def get_height_in_pixels(self):
return self.__height_in_pixels
#accepts(object, Style.XFStyle)
def set_style(self, style):
self.__adjust_height(style)
self.__xf_index = self.__parent_wb.add_style(style)
def get_xf_index(self):
return self.__xf_index
def get_cells_count(self):
return len(self.__cells)
def get_min_col(self):
return self.__min_col_idx
def get_max_col(self):
return self.__min_col_idx
def get_str_count(self):
return self.__total_str
def get_row_biff_data(self):
height_options = (self.height & 0x07FFF)
height_options |= (self.has_default_height & 0x01) << 15
options = (self.level & 0x07) << 0
options |= (self.collapse & 0x01) << 4
options |= (self.hidden & 0x01) << 5
options |= (0x00 & 0x01) << 6
options |= (0x01 & 0x01) << 8
if self.__xf_index != 0x0F:
options |= (0x01 & 0x01) << 7
else:
options |= (0x00 & 0x01) << 7
options |= (self.__xf_index & 0x0FFF) << 16
options |= (0x00 & self.space_above) << 28
options |= (0x00 & self.space_below) << 29
return BIFFRecords.RowRecord(self.__idx, self.__min_col_idx, self.__max_col_idx, height_options, options).get()
def get_cells_biff_data(self):
return ''.join([ cell.get_biff_data() for cell in self.__cells ])
def get_index(self):
return self.__idx
#accepts(object, int, (str, unicode, int, float, dt.datetime, dt.time, dt.date, ExcelFormula.Formula), Style.XFStyle)
def write(self, col, label, style):
self.__adjust_height(style)
self.__adjust_bound_col_idx(col)
if isinstance(label, (str, unicode)):
if len(label) > 0:
self.__cells.extend([ Cell.StrCell(self, col, self.__parent_wb.add_style(style), self.__parent_wb.add_str(label)) ])
self.__total_str += 1
else:
self.__cells.extend([ Cell.BlankCell(self, col, self.__parent_wb.add_style(style)) ])
elif isinstance(label, (int, float)):
self.__cells.extend([ Cell.NumberCell(self, col, self.__parent_wb.add_style(style), label) ])
elif isinstance(label, (dt.datetime, dt.time)):
self.__cells.extend([ Cell.NumberCell(self, col, self.__parent_wb.add_style(style), self.__excel_date_dt(label)) ])
else:
self.__cells.extend([ Cell.FormulaCell(self, col, self.__parent_wb.add_style(style), label) ])
#accepts(object, int, int, Style.XFStyle)
def write_blanks(self, c1, c2, style):
self.__adjust_height(style)
self.__adjust_bound_col_idx(c1, c2)
self.__cells.extend([ Cell.MulBlankCell(self, c1, c2, self.__parent_wb.add_style(style)) ])

View File

@ -0,0 +1,197 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
__rev_id__ = """$Id: Style.py,v 1.4 2005/07/20 07:24:11 rvk Exp $"""
import Formatting
from BIFFRecords import *
_default_num_format = 'general'
_default_font = Formatting.Font()
_default_alignment = Formatting.Alignment()
_default_borders = Formatting.Borders()
_default_pattern = Formatting.Pattern()
_default_protection = Formatting.Protection()
class XFStyle(object):
def __init__(self):
self.num_format_str = _default_num_format
self.font = _default_font
self.alignment = _default_alignment
self.borders = _default_borders
self.pattern = _default_pattern
self.protection = _default_protection
class StyleCollection(object):
_std_num_fmt_list = [
'general',
'0',
'0.00',
'#,##0',
'#,##0.00',
'"$"#,##0_);("$"#,##',
'"$"#,##0_);[Red]("$"#,##',
'"$"#,##0.00_);("$"#,##',
'"$"#,##0.00_);[Red]("$"#,##',
'0%',
'0.00%',
'0.00E+00',
'# ?/?',
'# ??/??',
'M/D/YY',
'D-MMM-YY',
'D-MMM',
'MMM-YY',
'h:mm AM/PM',
'h:mm:ss AM/PM',
'h:mm',
'h:mm:ss',
'M/D/YY h:mm',
'_(#,##0_);(#,##0)',
'_(#,##0_);[Red](#,##0)',
'_(#,##0.00_);(#,##0.00)',
'_(#,##0.00_);[Red](#,##0.00)',
'_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)',
'_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)',
'_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)',
'_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)',
'mm:ss',
'[h]:mm:ss',
'mm:ss.0',
'##0.0E+0',
'@'
]
def __init__(self):
self._fonts = {}
self._fonts[Formatting.Font()] = 0
self._fonts[Formatting.Font()] = 1
self._fonts[Formatting.Font()] = 2
self._fonts[Formatting.Font()] = 3
# The font with index 4 is omitted in all BIFF versions
self._fonts[Formatting.Font()] = 5
self._num_formats = {}
for fmtidx, fmtstr in zip(range(0, 23), StyleCollection._std_num_fmt_list[0:23]):
self._num_formats[fmtstr] = fmtidx
for fmtidx, fmtstr in zip(range(37, 50), StyleCollection._std_num_fmt_list[23:]):
self._num_formats[fmtstr] = fmtidx
self._xf = {}
self.default_style = XFStyle()
self._default_xf = self._add_style(self.default_style)[0]
def add(self, style):
if style == None:
return 0x10
return self._add_style(style)[1]
def _add_style(self, style):
num_format_str = style.num_format_str
if num_format_str in self._num_formats:
num_format_idx = self._num_formats[num_format_str]
else:
num_format_idx = 163 + len(self._num_formats) - len(StyleCollection._std_num_fmt_list)
self._num_formats[num_format_str] = num_format_idx
font = style.font
if font in self._fonts:
font_idx = self._fonts[font]
else:
font_idx = len(self._fonts) + 1
self._fonts[font] = font_idx
xf = (font_idx, num_format_idx, style.alignment, style.borders, style.pattern, style.protection)
if xf in self._xf:
xf_index = self._xf[xf]
else:
xf_index = 0x10 + len(self._xf)
self._xf[xf] = xf_index
return xf, xf_index
def get_biff_data(self):
result = ''
result += self._all_fonts()
result += self._all_num_formats()
result += self._all_cell_styles()
result += self._all_styles()
return result
def _all_fonts(self):
result = ''
i = sorted([(v, k) for k, v in self._fonts.items()])
for font_idx, font in i:
result += font.get_biff_record().get()
return result
def _all_num_formats(self):
result = ''
i = sorted([(v, k) for k, v in self._num_formats.items() if v>=163])
for fmtidx, fmtstr in i:
result += NumberFormatRecord(fmtidx, fmtstr).get()
return result
def _all_cell_styles(self):
result = ''
for i in range(0, 16):
result += XFRecord(self._default_xf, 'style').get()
i = sorted([(v, k) for k, v in self._xf.items()])
for xf_idx, xf in i:
result += XFRecord(xf).get()
return result
def _all_styles(self):
return StyleRecord().get()
if __name__ == '__main__':
sc = StyleCollection()
f = file('styles.bin', 'wb')
f.write(sc.get_biff_data())
f.close()

View File

@ -0,0 +1,135 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
'''
From BIFF8 on, strings are always stored using UTF-16LE text encoding. The
character array is a sequence of 16-bit values4. Additionally it is
possible to use a compressed format, which omits the high bytes of all
characters, if they are all zero.
The following tables describe the standard format of the entire string, but
in many records the strings differ from this format. This will be mentioned
separately. It is possible (but not required) to store Rich-Text formatting
information and Asian phonetic information inside a Unicode string. This
results in four different ways to store a string. The character array
is not zero-terminated.
The string consists of the character count (as usual an 8-bit value or
a 16-bit value), option flags, the character array and optional formatting
information. If the string is empty, sometimes the option flags field will
not occur. This is mentioned at the respective place.
Offset Size Contents
0 1 or 2 Length of the string (character count, ln)
1 or 2 1 Option flags:
Bit Mask Contents
0 01H Character compression (ccompr):
0 = Compressed (8-bit characters)
1 = Uncompressed (16-bit characters)
2 04H Asian phonetic settings (phonetic):
0 = Does not contain Asian phonetic settings
1 = Contains Asian phonetic settings
3 08H Rich-Text settings (richtext):
0 = Does not contain Rich-Text settings
1 = Contains Rich-Text settings
[2 or 3] 2 (optional, only if richtext=1) Number of Rich-Text formatting runs (rt)
[var.] 4 (optional, only if phonetic=1) Size of Asian phonetic settings block (in bytes, sz)
var. ln or
2·ln Character array (8-bit characters or 16-bit characters, dependent on ccompr)
[var.] 4·rt (optional, only if richtext=1) List of rt formatting runs
[var.] sz (optional, only if phonetic=1) Asian Phonetic Settings Block
'''
__rev_id__ = """$Id: UnicodeUtils.py,v 1.4 2005/07/20 07:24:11 rvk Exp $"""
import struct
DEFAULT_ENCODING = 'cp1251'
def u2ints(ustr):
ints = [ord(uchr) for uchr in ustr]
return ints
def u2bytes(ustr):
ints = u2ints(ustr)
return struct.pack('<' + 'H'*len(ints), *ints)
def upack2(_str):
try:
ustr = u2bytes(unicode(_str, 'ascii'))
return struct.pack('<HB', len(_str), 0) + _str
except:
if isinstance(_str, unicode):
ustr = u2bytes(_str)
else:
ustr = u2bytes(unicode(_str, DEFAULT_ENCODING))
return struct.pack('<HB', len(_str), 1) + ustr
def upack1(_str):
try:
ustr = u2bytes(unicode(_str, 'ascii'))
return struct.pack('BB', len(_str), 0) + _str
except:
if isinstance(_str, unicode):
ustr = u2bytes(_str)
else:
ustr = u2bytes(unicode(_str, DEFAULT_ENCODING))
return struct.pack('BB', len(_str), 1) + ustr
if __name__ == '__main__':
f = file('out0.bin', 'wb')
f.write(u2bytes('þíèêîä: unicode'))
f.close()
f = file('out1.bin', 'wb')
f.write(upack1('þíèêîä: unicode'))
f.close()
f = file('out2.bin', 'wb')
f.write(upack2('þíèêîä: unicode'))
f.close()

View File

@ -0,0 +1,165 @@
# pyXLWriter: A library for generating Excel Spreadsheets
# Copyright (c) 2004 Evgeny Filatov <fufff@users.sourceforge.net>
# Copyright (c) 2002-2004 John McNamara (Perl Spreadsheet::WriteExcel)
#
# This library is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#----------------------------------------------------------------------------
# This module was written/ported from PERL Spreadsheet::WriteExcel module
# The author of the PERL Spreadsheet::WriteExcel module is John McNamara
# <jmcnamara@cpan.org>
#----------------------------------------------------------------------------
# See the README.txt distributed with pyXLWriter for more details.
# Portions are (C) Roman V. Kiseliov, 2005
"""pyXLWriter.utilites
Utilities for work with reference to cells
"""
__rev_id__ = """$Id: Utils.py,v 1.1 2005/08/11 08:53:48 rvk Exp $"""
import re
from struct import pack
from ExcelMagic import MAX_ROW, MAX_COL
_re_cell_ex = re.compile(r"(\$?)([A-I]?[A-Z])(\$?)(\d+)")
_re_row_range = re.compile(r"\$?(\d+):\$?(\d+)")
_re_col_range = re.compile(r"\$?([A-I]?[A-Z]):\$?([A-I]?[A-Z])")
_re_cell_range = re.compile(r"\$?([A-I]?[A-Z]\$?\d+):\$?([A-I]?[A-Z]\$?\d+)")
_re_cell_ref = re.compile(r"\$?([A-I]?[A-Z]\$?\d+)")
def col_by_name(colname):
"""
"""
col = 0
pow = 1
for i in xrange(len(colname)-1, -1, -1):
ch = colname[i]
col += (ord(ch) - ord('A') + 1) * pow
pow *= 26
return col - 1
def cell_to_rowcol(cell):
"""Convert an Excel cell reference string in A1 notation
to numeric row/col notation.
Returns: row, col, row_abs, col_abs
"""
m = _re_cell_ex.match(cell)
if not m:
raise Exception("Error in cell format")
col_abs, col, row_abs, row = m.groups()
row_abs = bool(row_abs)
col_abs = bool(col_abs)
row = int(row) - 1
col = col_by_name(col)
return row, col, row_abs, col_abs
def cell_to_rowcol2(cell):
"""Convert an Excel cell reference string in A1 notation
to numeric row/col notation.
Returns: row, col
"""
m = _re_cell_ex.match(cell)
if not m:
raise Exception("Error in cell format")
col_abs, col, row_abs, row = m.groups()
# Convert base26 column string to number
# All your Base are belong to us.
row = int(row) - 1
col = col_by_name(col)
return row, col
def rowcol_to_cell(row, col, row_abs=False, col_abs=False):
"""Convert numeric row/col notation to an Excel cell reference string in
A1 notation.
"""
d = col // 26
m = col % 26
chr1 = "" # Most significant character in AA1
if row_abs:
row_abs = '$'
else:
row_abs = ''
if col_abs:
col_abs = '$'
else:
col_abs = ''
if d > 0:
chr1 = chr(ord('A') + d - 1)
chr2 = chr(ord('A') + m)
# Zero index to 1-index
return col_abs + chr1 + chr2 + row_abs + str(row + 1)
def cellrange_to_rowcol_pair(cellrange):
"""Convert cell range string in A1 notation to numeric row/col
pair.
Returns: row1, col1, row2, col2
"""
cellrange = cellrange.upper()
# Convert a row range: '1:3'
res = _re_row_range.match(cellrange)
if res:
row1 = int(res.group(1)) - 1
col1 = 0
row2 = int(res.group(2)) - 1
col2 = -1
return row1, col1, row2, col2
# Convert a column range: 'A:A' or 'B:G'.
# A range such as A:A is equivalent to A1:A16384, so add rows as required
res = _re_col_range.match(cellrange)
if res:
col1 = col_by_name(res.group(1))
row1 = 0
col2 = col_by_name(res.group(2))
row2 = -1
return row1, col1, row2, col2
# Convert a cell range: 'A1:B7'
res = _re_cell_range.match(cellrange)
if res:
row1, col1 = cell_to_rowcol2(res.group(1))
row2, col2 = cell_to_rowcol2(res.group(2))
return row1, col1, row2, col2
# Convert a cell reference: 'A1' or 'AD2000'
res = _re_cell_ref.match(cellrange)
if res:
row1, col1 = cell_to_rowcol2(res.group(1))
return row1, col1, row1, col1
raise Exception("Unknown cell reference %s" % (cell))
def cell_to_packed_rowcol(cell):
""" pack row and column into the required 4 byte format """
row, col, row_abs, col_abs = cell_to_rowcol(cell)
if col >= MAX_COL:
raise Exception("Column %s greater than IV in formula" % cell)
if row >= MAX_ROW: # this for BIFF8. for BIFF7 available 2^14
raise Exception("Row %s greater than %d in formula" % (cell, MAX_ROW))
col |= int(not row_abs) << 15
col |= int(not col_abs) << 14
return row, col

View File

@ -0,0 +1,576 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
# Copyright (C) 2005 Roman V. Kiseliov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. All advertising materials mentioning features or use of this
# software must display the following acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# 4. Redistributions of any form whatsoever must retain the following
# acknowledgment:
# "This product includes software developed by
# Roman V. Kiseliov <roman@kiseliov.ru>."
#
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
'''
Record Order in BIFF8
Workbook Globals Substream
BOF Type = workbook globals
Interface Header
MMS
Interface End
WRITEACCESS
CODEPAGE
DSF
TABID
FNGROUPCOUNT
Workbook Protection Block
WINDOWPROTECT
PROTECT
PASSWORD
PROT4REV
PROT4REVPASS
BACKUP
HIDEOBJ
WINDOW1
DATEMODE
PRECISION
REFRESHALL
BOOKBOOL
FONT +
FORMAT *
XF +
STYLE +
? PALETTE
USESELFS
BOUNDSHEET +
COUNTRY
? Link Table
SST
ExtSST
EOF
'''
__rev_id__ = """$Id: Workbook.py,v 1.5 2005/10/26 07:44:24 rvk Exp $"""
import BIFFRecords
import Style
from Deco import accepts, returns
class Workbook(object):
#################################################################
## Constructor
#################################################################
#accepts(object)
def __init__(self):
self.__owner = 'None'
self.__country_code = 0x07
self.__wnd_protect = 0
self.__obj_protect = 0
self.__protect = 0
self.__backup_on_save = 0
# for WINDOW1 record
self.__hpos_twips = 0x01E0
self.__vpos_twips = 0x005A
self.__width_twips = 0x3FCF
self.__height_twips = 0x2A4E
self.__active_sheet = 0
self.__first_tab_index = 0
self.__selected_tabs = 0x01
self.__tab_width_twips = 0x0258
self.__wnd_hidden = 0
self.__wnd_mini = 0
self.__hscroll_visible = 1
self.__vscroll_visible = 1
self.__tabs_visible = 1
self.__styles = Style.StyleCollection()
self.__dates_1904 = 0
self.__use_cell_values = 1
self.__sst = BIFFRecords.SharedStringTable()
self.__worksheets = []
#################################################################
## Properties, "getters", "setters"
#################################################################
#accepts(object, str)
def set_owner(self, value):
self.__owner = value
def get_owner(self):
return self.__owner
owner = property(get_owner, set_owner)
#################################################################
#accepts(object, int)
def set_country_code(self, value):
self.__country_code = value
def get_country_code(self):
return self.__country_code
country_code = property(get_country_code, set_country_code)
#################################################################
#accepts(object, bool)
def set_wnd_protect(self, value):
self.__wnd_protect = int(value)
def get_wnd_protect(self):
return bool(self.__wnd_protect)
wnd_protect = property(get_wnd_protect, set_wnd_protect)
#################################################################
#accepts(object, bool)
def set_obj_protect(self, value):
self.__obj_protect = int(value)
def get_obj_protect(self):
return bool(self.__obj_protect)
obj_protect = property(get_obj_protect, set_obj_protect)
#################################################################
#accepts(object, bool)
def set_protect(self, value):
self.__protect = int(value)
def get_protect(self):
return bool(self.__protect)
protect = property(get_protect, set_protect)
#################################################################
#accepts(object, bool)
def set_backup_on_save(self, value):
self.__backup_on_save = int(value)
def get_backup_on_save(self):
return bool(self.__backup_on_save)
backup_on_save = property(get_backup_on_save, set_backup_on_save)
#################################################################
#accepts(object, int)
def set_hpos(self, value):
self.__hpos_twips = value & 0xFFFF
def get_hpos(self):
return self.__hpos_twips
hpos = property(get_hpos, set_hpos)
#################################################################
#accepts(object, int)
def set_vpos(self, value):
self.__vpos_twips = value & 0xFFFF
def get_vpos(self):
return self.__vpos_twips
vpos = property(get_vpos, set_vpos)
#################################################################
#accepts(object, int)
def set_width(self, value):
self.__width_twips = value & 0xFFFF
def get_width(self):
return self.__width_twips
width = property(get_width, set_width)
#################################################################
#accepts(object, int)
def set_height(self, value):
self.__height_twips = value & 0xFFFF
def get_height(self):
return self.__height_twips
height = property(get_height, set_height)
#################################################################
#accepts(object, int)
def set_active_sheet(self, value):
self.__active_sheet = value & 0xFFFF
self.__first_tab_index = self.__active_sheet
def get_active_sheet(self):
return self.__active_sheet
active_sheet = property(get_active_sheet, set_active_sheet)
#################################################################
#accepts(object, int)
def set_tab_width(self, value):
self.__tab_width_twips = value & 0xFFFF
def get_tab_width(self):
return self.__tab_width_twips
tab_width = property(get_tab_width, set_tab_width)
#################################################################
#accepts(object, bool)
def set_wnd_visible(self, value):
self.__wnd_hidden = int(not value)
def get_wnd_visible(self):
return not bool(self.__wnd_hidden)
wnd_visible = property(get_wnd_visible, set_wnd_visible)
#################################################################
#accepts(object, bool)
def set_wnd_mini(self, value):
self.__wnd_mini = int(value)
def get_wnd_mini(self):
return bool(self.__wnd_mini)
wnd_mini = property(get_wnd_mini, set_wnd_mini)
#################################################################
#accepts(object, bool)
def set_hscroll_visible(self, value):
self.__hscroll_visible = int(value)
def get_hscroll_visible(self):
return bool(self.__hscroll_visible)
hscroll_visible = property(get_hscroll_visible, set_hscroll_visible)
#################################################################
#accepts(object, bool)
def set_vscroll_visible(self, value):
self.__vscroll_visible = int(value)
def get_vscroll_visible(self):
return bool(self.__vscroll_visible)
vscroll_visible = property(get_vscroll_visible, set_vscroll_visible)
#################################################################
#accepts(object, bool)
def set_tabs_visible(self, value):
self.__tabs_visible = int(value)
def get_tabs_visible(self):
return bool(self.__tabs_visible)
tabs_visible = property(get_tabs_visible, set_tabs_visible)
#################################################################
#accepts(object, bool)
def set_dates_1904(self, value):
self.__dates_1904 = int(value)
def get_dates_1904(self):
return bool(self.__dates_1904)
dates_1904 = property(get_dates_1904, set_dates_1904)
#################################################################
#accepts(object, bool)
def set_use_cell_values(self, value):
self.__use_cell_values = int(value)
def get_use_cell_values(self):
return bool(self.__use_cell_values)
use_cell_values = property(get_use_cell_values, set_use_cell_values)
#################################################################
def get_default_style(self):
return self.__styles.default_style
default_style = property(get_default_style)
##################################################################
## Methods
##################################################################
#accepts(object, Style.XFStyle)
def add_style(self, style):
return self.__styles.add(style)
#accepts(object, (str, unicode))
def add_str(self, s):
return self.__sst.add_str(s)
#accepts(object, str)
def str_index(self, s):
return self.__sst.str_index(s)
#accepts(object, (str, unicode))
def add_sheet(self, sheetname):
import Worksheet
self.__worksheets.append(Worksheet.Worksheet(sheetname, self))
return self.__worksheets[-1]
#accepts(object, int)
def get_sheet(self, sheetnum):
return self.__worksheets[sheetnum]
##################################################################
## BIFF records generation
##################################################################
def __bof_rec(self):
return BIFFRecords.Biff8BOFRecord(BIFFRecords.Biff8BOFRecord.BOOK_GLOBAL).get()
def __eof_rec(self):
return BIFFRecords.EOFRecord().get()
def __intf_hdr_rec(self):
return BIFFRecords.InteraceHdrRecord().get()
def __intf_end_rec(self):
return BIFFRecords.InteraceEndRecord().get()
def __intf_mms_rec(self):
return BIFFRecords.MMSRecord().get()
def __write_access_rec(self):
return BIFFRecords.WriteAccessRecord(self.__owner).get()
def __wnd_protect_rec(self):
return BIFFRecords.WindowProtectRecord(self.__wnd_protect).get()
def __obj_protect_rec(self):
return BIFFRecords.ObjectProtectRecord(self.__obj_protect).get()
def __protect_rec(self):
return BIFFRecords.ProtectRecord(self.__protect).get()
def __password_rec(self):
return BIFFRecords.PasswordRecord().get()
def __prot4rev_rec(self):
return BIFFRecords.Prot4RevRecord().get()
def __prot4rev_pass_rec(self):
return BIFFRecords.Prot4RevPassRecord().get()
def __backup_rec(self):
return BIFFRecords.BackupRecord(self.__backup_on_save).get()
def __hide_obj_rec(self):
return BIFFRecords.HideObjRecord().get()
def __window1_rec(self):
flags = 0
flags |= (self.__wnd_hidden) << 0
flags |= (self.__wnd_mini) << 1
flags |= (self.__hscroll_visible) << 3
flags |= (self.__vscroll_visible) << 4
flags |= (self.__tabs_visible) << 5
return BIFFRecords.Window1Record(self.__hpos_twips, self.__vpos_twips,
self.__width_twips, self.__height_twips,
flags,
self.__active_sheet, self.__first_tab_index,
self.__selected_tabs, self.__tab_width_twips).get()
def __codepage_rec(self):
return BIFFRecords.CodepageBiff8Record().get()
def __country_rec(self):
return BIFFRecords.CountryRecord(self.__country_code, self.__country_code).get()
def __dsf_rec(self):
return BIFFRecords.DSFRecord().get()
def __tabid_rec(self):
return BIFFRecords.TabIDRecord(len(self.__worksheets)).get()
def __fngroupcount_rec(self):
return BIFFRecords.FnGroupCountRecord().get()
def __datemode_rec(self):
return BIFFRecords.DateModeRecord(self.__dates_1904).get()
def __precision_rec(self):
return BIFFRecords.PrecisionRecord(self.__use_cell_values).get()
def __refresh_all_rec(self):
return BIFFRecords.RefreshAllRecord().get()
def __bookbool_rec(self):
return BIFFRecords.BookBoolRecord().get()
def __all_fonts_num_formats_xf_styles_rec(self):
return self.__styles.get_biff_data()
def __palette_rec(self):
result = ''
return result
def __useselfs_rec(self):
return BIFFRecords.UseSelfsRecord().get()
def __boundsheets_rec(self, data_len_before, data_len_after, sheet_biff_lens):
# .................................
# BOUNDSEHEET0
# BOUNDSEHEET1
# BOUNDSEHEET2
# ..................................
# WORKSHEET0
# WORKSHEET1
# WORKSHEET2
boundsheets_len = 0
for sheet in self.__worksheets:
boundsheets_len += len(BIFFRecords.BoundSheetRecord(0x00L, sheet.hidden, sheet.name).get())
start = data_len_before + boundsheets_len + data_len_after
result = ''
for sheet_biff_len, sheet in zip(sheet_biff_lens, self.__worksheets):
result += BIFFRecords.BoundSheetRecord(start, sheet.hidden, sheet.name).get()
start += sheet_biff_len
return result
def __all_links_rec(self):
result = ''
return result
def __sst_rec(self):
return self.__sst.get_biff_record()
def __ext_sst_rec(self, abs_stream_pos):
return ''
#return BIFFRecords.ExtSSTRecord(abs_stream_pos, self.sst_record.str_placement,
#self.sst_record.portions_len).get()
def get_biff_data(self):
before = ''
before += self.__bof_rec()
before += self.__intf_hdr_rec()
before += self.__intf_mms_rec()
before += self.__intf_end_rec()
before += self.__write_access_rec()
before += self.__codepage_rec()
before += self.__dsf_rec()
before += self.__tabid_rec()
before += self.__fngroupcount_rec()
before += self.__wnd_protect_rec()
before += self.__protect_rec()
before += self.__obj_protect_rec()
before += self.__password_rec()
before += self.__prot4rev_rec()
before += self.__prot4rev_pass_rec()
before += self.__backup_rec()
before += self.__hide_obj_rec()
before += self.__window1_rec()
before += self.__datemode_rec()
before += self.__precision_rec()
before += self.__refresh_all_rec()
before += self.__bookbool_rec()
before += self.__all_fonts_num_formats_xf_styles_rec()
before += self.__palette_rec()
before += self.__useselfs_rec()
country = self.__country_rec()
all_links = self.__all_links_rec()
shared_str_table = self.__sst_rec()
after = country + all_links + shared_str_table
ext_sst = self.__ext_sst_rec(0) # need fake cause we need calc stream pos
eof = self.__eof_rec()
self.__worksheets[self.__active_sheet].selected = True
sheets = ''
sheet_biff_lens = []
for sheet in self.__worksheets:
data = sheet.get_biff_data()
sheets += data
sheet_biff_lens.append(len(data))
bundlesheets = self.__boundsheets_rec(len(before), len(after)+len(ext_sst)+len(eof), sheet_biff_lens)
sst_stream_pos = len(before) + len(bundlesheets) + len(country) + len(all_links)
ext_sst = self.__ext_sst_rec(sst_stream_pos)
return before + bundlesheets + after + ext_sst + eof + sheets
def save(self, filename):
import CompoundDoc
doc = CompoundDoc.XlsDoc()
doc.save(filename, self.get_biff_data())
def savetostr(self): # XXX ADDED BY EMMANUEL
import CompoundDoc
doc = CompoundDoc.XlsDoc()
return doc.savetostr(self.get_biff_data())
if __name__ == '__main__':
wb = Workbook()
f = file('workbook.bin', 'wb')
f.write(wb.get_biff_data())
f.close()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
# -*- coding: windows-1251 -*-
__rev_id__ = """$Id: __init__.py,v 1.6 2005/08/11 08:53:48 rvk Exp $"""
import sys
if sys.version_info[:2] < (2, 4):
def sorted(l, cmp=None, key=None, reverse=False):
tmp = list(l)
tmp.sort(cmp)
return tmp
import __builtin__
__builtin__.sorted = sorted
del __builtin__
## print >>sys.stderr, "Sorry, pyExcelerator requires Python 2.4 or later"
## sys.exit(1)
from Workbook import Workbook
from Worksheet import Worksheet
from Row import Row
from Column import Column
from Formatting import Font, Alignment, Borders, Pattern, Protection
from Style import XFStyle
from ImportXLS import *
from ExcelFormula import *

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More