OVH Cloud OVH Cloud

POO + Excel 2003 + SpreadSheetXML

8 réponses
Avatar
Didier Fraisse
Je souhaite générer un ensemble de fichiers excel.

Python + Win32COM se révélant être peu rapide car je ne peux générer qu'un
fichier à la fois,
j'envisage de générer d'abord les fichiers au format SpreadSheetXML en
multithread,
puis seulement de les convertir en XLS par Win32COM + Excel 2003

Que pensez-vous de cette approche ( désolé mais Excel est imposé ) ?

j'aimerais utiliser la POO mais j'avoue n'avoir aucune idée de la façon
d'aborder le problème.
bien sur je peux toujours le faire en programmation structurée.

Merci de vos futures réponses

8 réponses

Avatar
Didier Fraisse
juste un petit exemple de ce que je veux obtenir

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>10005</WindowHeight>
<WindowWidth>10005</WindowWidth>
<WindowTopX>120</WindowTopX>
<WindowTopY>135</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s21">
<NumberFormat ss:Format="0"/>
</Style>
<Style ss:ID="s22">
<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
</Style>
<Style ss:ID="s23">
<NumberFormat ss:Format="Standard"/>
</Style>
<Style ss:ID="s25">
<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
<Font ss:Size="14" ss:Bold="1"/>
</Style>
<Style ss:ID="s26">
<Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
<Font ss:Size="8" ss:Bold="1"/>
<NumberFormat ss:Format="0"/>
</Style>
<Style ss:ID="s27">
<Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
<Font ss:Size="8" ss:Bold="1"/>
</Style>
<Style ss:ID="s28">
<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
<Font ss:Size="8" ss:Bold="1"/>
</Style>
<Style ss:ID="s29">
<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
<Font ss:Size="8" ss:Bold="1"/>
<NumberFormat ss:Format="Standard"/>
</Style>
<Style ss:ID="s30">
<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
<Font ss:Size="8" ss:Bold="1"/>
</Style>
<Style ss:ID="s31">
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
<NumberFormat ss:Format="0"/>
</Style>
<Style ss:ID="s32">
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
</Style>
<Style ss:ID="s33">
<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
</Style>
<Style ss:ID="s34">
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
<NumberFormat ss:Format="Standard"/>
</Style>
<Style ss:ID="s35">
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
</Borders>
</Style>
<Style ss:ID="s36">
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous"/>
</Borders>
<NumberFormat ss:Format="0"/>
</Style>
<Style ss:ID="s37">
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous"/>
</Borders>
</Style>
<Style ss:ID="s38">
<Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous"/>
</Borders>
</Style>
<Style ss:ID="s39">
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous"/>
<Border ss:Position="Top" ss:LineStyle="Continuous"/>
</Borders>
<NumberFormat ss:Format="Standard"/>
</Style>
<Style ss:ID="s40">
<Borders>
<Border ss:Position="Bottom" ss:LineStyle="Continuous"/>
<Border ss:Position="Left" ss:LineStyle="Continuous"/>
<Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
<Border ss:Position="Top" ss:LineStyle="Continuous"/>
</Borders>
</Style>
</Styles>
<Worksheet ss:Name="G980441">
<Table ss:ExpandedColumnCount="256" ss:ExpandedRowCount="5"
x:FullColumns="1"
x:FullRows="1" ss:DefaultColumnWidth="60">
<Column ss:StyleID="s21" ss:Width="73.5"/>
<Column ss:Width="117.75"/>
<Column ss:StyleID="s22" ss:Width="55.5"/>
<Column ss:Width="81"/>
<Column ss:Width="42"/>
<Column ss:Width="54"/>
<Column ss:Width="40.5"/>
<Column ss:StyleID="s23" ss:Width="42.75"/>
<Column ss:StyleID="s22" ss:Width="50.25"/>
<Column ss:Width="12"/>
<Column ss:Width="42"/>
<Column ss:AutoFitWidth="0" ss:Width="30" ss:Span="244"/>
<Row ss:AutoFitHeight="0" ss:Height="18">
<Cell ss:MergeAcross="10" ss:StyleID="s25"><Data
ss:Type="String">VORRATLISTE</Data></Cell>
</Row>
<Row ss:Index="3" ss:AutoFitHeight="0" ss:Height="22.5">
<Cell ss:StyleID="s26"><Data ss:Type="String">GENCOD</Data></Cell>
<Cell ss:StyleID="s27"><Data ss:Type="String">BEZEICHNUNG</Data></Cell>
<Cell ss:StyleID="s27"><Data ss:Type="String">ABMESSUNG</Data></Cell>
<Cell ss:StyleID="s27"><Data ss:Type="String">OBERFLAECHE</Data></Cell>
<Cell ss:StyleID="s28"><Data
ss:Type="String">VORRAT&#10;MENGE</Data></Cell>
<Cell ss:StyleID="s28"><Data ss:Type="String">MENGE
/&#10;SCHACHTEL</Data></Cell>
<Cell ss:StyleID="s28"><Data ss:Type="String">MINDEST
&#10;MENGE</Data></Cell>
<Cell ss:StyleID="s29"><Data ss:Type="String">NETTO
&#10;PREIS</Data></Cell>
<Cell ss:StyleID="s27"><Data ss:Type="String">WAEHRUNG</Data></Cell>
<Cell ss:StyleID="s27"><Data ss:Type="String"> </Data></Cell>
<Cell ss:StyleID="s30"><Data ss:Type="String">PALETTE
&#10;MENGE</Data></Cell>
</Row>
<Row>
<Cell ss:StyleID="s31"><Data
ss:Type="Number">3473575320021</Data></Cell>
<Cell ss:StyleID="s32"><Data ss:Type="String">NF EN ISO 4017
6.8</Data></Cell>
<Cell ss:StyleID="s33"><Data ss:Type="String">3 X 10</Data></Cell>
<Cell ss:StyleID="s32"><Data ss:Type="String">VERZINKT</Data></Cell>
<Cell ss:StyleID="s32"><Data ss:Type="Number">43000</Data></Cell>
<Cell ss:StyleID="s32"><Data ss:Type="Number">500</Data></Cell>
<Cell ss:StyleID="s32"><Data ss:Type="Number">500</Data></Cell>
<Cell ss:StyleID="s34"><Data ss:Type="Number">0.7</Data></Cell>
<Cell ss:StyleID="s33"><Data ss:Type="String">EUR</Data></Cell>
<Cell ss:StyleID="s32"><Data ss:Type="String">C</Data></Cell>
<Cell ss:StyleID="s35"><Data ss:Type="Number">1152000</Data></Cell>
</Row>
<Row>
<Cell ss:StyleID="s36"><Data
ss:Type="Number">3473575320052</Data></Cell>
<Cell ss:StyleID="s37"><Data ss:Type="String">NF EN ISO 4017
6.8</Data></Cell>
<Cell ss:StyleID="s38"><Data ss:Type="String">3 X 12</Data></Cell>
<Cell ss:StyleID="s37"><Data ss:Type="String">VERZINKT</Data></Cell>
<Cell ss:StyleID="s37"><Data ss:Type="Number">35000</Data></Cell>
<Cell ss:StyleID="s37"><Data ss:Type="Number">500</Data></Cell>
<Cell ss:StyleID="s37"><Data ss:Type="Number">500</Data></Cell>
<Cell ss:StyleID="s39"><Data ss:Type="Number">0.7</Data></Cell>
<Cell ss:StyleID="s38"><Data ss:Type="String">EUR</Data></Cell>
<Cell ss:StyleID="s37"><Data ss:Type="String">C</Data></Cell>
<Cell ss:StyleID="s40"><Data ss:Type="Number">864000</Data></Cell>
</Row>
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Layout x:CenterHorizontal="1"/>
<Header x:Margin="0"/>
<Footer x:Margin="0.2" x:Data="&amp;C&amp;8&amp;P/&amp;T&amp;D&amp;8
30/09/2004"/>
<PageMargins x:Bottom="0.4" x:Left="0.2" x:Right="0.2" x:Top="0"/>
</PageSetup>
<FitToPage/>
<Print>
<FitHeight>0</FitHeight>
<ValidPrinterInfo/>
<PaperSizeIndex>9</PaperSizeIndex>
</Print>
<Selected/>
<FreezePanes/>
<FrozenNoSplit/>
<SplitHorizontal>3</SplitHorizontal>
<TopRowBottomPane>3</TopRowBottomPane>
<ActivePane>2</ActivePane>
</WorksheetOptions>
</Worksheet>
</Workbook>
Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonsoir !

Perso, je trouve l'interface COM assez rapide (je passe plus de mille
paramètres par seconde).

Néanmoins, l'idée de passer par XML me semble intéressante. Toutefois, vu
la "verbosité" d' Excel dans ce domaine, Je pense que tu t'attaque à un
grand truc.

Selon la variété des formats de feuilles (fichiers) excel, il serait
peut-être possible de créer des fichiers-squelettes (templates) sous excel,
de les sauvegarder en XML, puis de travailler par modification avec Python.

@-salutations
--
Michel Claveau
Avatar
F. Petitjean
On Thu, 30 Sep 2004 14:18:13 +0200, Didier Fraisse wrote:
Je souhaite générer un ensemble de fichiers excel.

Depuis python ?


Pourquoi ne pas utiliser pyXlWriter ?
extrait du setup.py de ca paquet :

author = "Evgeny Filatov",
author_email = "",
url = "http://sourceforge.net/projects/pyxlwriter/",

En direcit de la Russie.
Je conseillerais simplement de passer un coup de pyChecker (ou mieux de
pylint de logilab.org) pour corriger je ne sais plus quelle petite faute
de frappe.

Amicalement.

Avatar
Didier Fraisse
Bonsoir

Perso, je trouve l'interface COM assez rapide (je passe plus de mille
paramètres par seconde).

pour moi il me faut 2 minutes pour générer un fichier excel à partir d'un

fichier de 3000 lignes x 11 cellules
( voir modèle dans les messages précédents )

Il serait peut-être possible de créer des fichiers-squelettes (templates)
sous excel,
de les sauvegarder en XML, puis de travailler par modification avec
Python.
c'est exactement ce que j'avais en tête.

je n'ai pas l'intention de me lancer dans l'écriture d'un wrapper
SpreadsheetML ( du moins pas tout de suite ).
les parties variables du fichiers xml sont
* le titre (VORRATLISTE, STOCK LIST, LISTE DES STOCKS ) en fonction de
la langue
<Cell ss:MergeAcross="10" ss:StyleID="s25"><Data
ss:Type="String">VORRATLISTE</Data></Cell>

* l'entete de tableau en fonction de la langue

* et bien sur les n lignes de données

Salutations
Didier FRAISSE

Avatar
Gilles Lenfant
"Didier Fraisse" a écrit dans le message de
news:415bf966$0$30920$
Je souhaite générer un ensemble de fichiers excel.

Python + Win32COM se révélant être peu rapide car je ne peux générer qu'un
fichier à la fois,


Le problême n'est pas la rapidité des interfaces COM (j'utilise le parser
MSXML en mode COM depuis Python, c'est le parser le plus rapide du monde Win
:o).
En pilotant les applications MS Office par COM, ça va bien plus vite si on
passe les dites applications en mode invisible.
Le mode visible sert uniquement pour la mise au point des scripts.
Je ne me souviens plus comment on fait mais en googlant un peu, ou dans
l'aide d'Excel (section programmeur)...

j'envisage de générer d'abord les fichiers au format SpreadSheetXML en
multithread,
puis seulement de les convertir en XLS par Win32COM + Excel 2003

Que pensez-vous de cette approche ( désolé mais Excel est imposé ) ?

j'aimerais utiliser la POO mais j'avoue n'avoir aucune idée de la façon
d'aborder le problème.


C'est un autre problème :o)
Voir tous les milliers d'articles consacrés à la pensée par objet expliquée
aux newbies.
Ne t'en fais pas une montagne : avec Python, le passage à l'acte est un jeu
d'enfant.

bien sur je peux toujours le faire en programmation structurée.


Contrairement à Smalltalk ou certains autres langages, Python permet aussi
de faire de la prog structurée classique (avec fonctions, variables locales
et globales...), mais bon, pourquoi faire obscur et verbeux quand on peut
faire clair et concis ;o)


Merci de vos futures réponses




Avatar
Didier Fraisse
bonjour Gilles

Le mode visible sert uniquement pour la mise au point des scripts.
Je ne me souviens plus comment on fait.


excel.DisplayAlerts = False (pour te rafraichir la mémoire)

le problème n'est pas là car je le savais
par contre , j'ai pu diviser mon temps d'execution par 4 en remplacant

csvreader = csv.reader(file(txtFile), dialect='excel',
delimiter=';')
for row in csvreader:
ligne += 1
wks.Range(wks.Cells(ligne,1),wks.Cells(ligne,12)).Value = (
(row[0].strip()),
(row[1].strip()),
(row[2].strip()),
(row[3].strip()),
(row[4].strip()),
(row[5].strip()),
(row[6].strip()),
float((row[7].strip()).replace(',','.')),
(row[8].strip()),
(row[9].strip()),
(row[10].strip()),
(row[11].strip()),
)


40 secondes pour un fichier de 3000 lignes

par
csvreader = csv.reader(file(txtFile), dialect='excel',
delimiter=';')
xlsdata = []
for row in csvreader:
ligne += 1
xlsdata.append((
(row[0].strip()),
(row[1].strip()),
(row[2].strip()),
(row[3].strip()),
(row[4].strip()),
(row[5].strip()),
(row[6].strip()),
float((row[7].strip()).replace(',','.')),
(row[8].strip()),
(row[9].strip()),
(row[10].strip()),
(row[11].strip()),)
)
wks.Range(wks.Cells(4,1),wks.Cells(ligne,12)).Value = xlsdata

10 secondes pour le même fichier de 3000 lignes
bien sur il y a le risque que j'explose mon occupation mémoire si le fichier
csv est vraiment gros :-)

mais bon, pourquoi faire obscur et verbeux quand on peut faire clair et
concis ;o)

soit mais qu'elle est l'approche obscure et verbeuse et celle claire et
concise
entre programmation structurée et POO ?

Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonjour !


Avec le code suivant, je remplis 3000 lignes de 11 colonnes, en moins de 0,1
seconde :

import win32com.client
import time,string

excel = win32com.client.Dispatch('Excel.Application')
excel.Visible = 0
#excel.Application.DisplayAlerts = False # pour eviter les msg d'alerte
(+ rapide si Visible=1)
excel.Workbooks.Add()

deb=time.time()

lst=[]
l2=[22,33,44,55,66,77,88,99,1010,1111,1212]
for i in xrange(3000):
lst.append(l2)
excel.Range(excel.Cells(1,2),excel.Cells(3000,12)).Value = lst

fin=time.time()
print fin-deb
excel.Visible = 1



A noter que excel.Visible = 0 est au moins aussi efficace pour gagner du
temps, que excel.Application.DisplayAlerts = False



Concernant la différence programmation structurée / POO, je suis comme toi,
dubitatif.
Finalement, je suis arrivé à la conclusion que les deux formes existent, que
chacune est plus ou moins adaptée, selon les projets et/ou la façon de
penser des développeurs, sans qu'il y ait d'avantages réellement
déterminants, pour l'une ou l'autre.

Un des avantages de Python, c'est d'offrir le choix.


Bonne journée
--
Michel Claveau
Avatar
Xavier Combelle
Concernant la différence programmation structurée / POO, je suis comme toi,
dubitatif.
Finalement, je suis arrivé à la conclusion que les deux formes existent, que
chacune est plus ou moins adaptée, selon les projets et/ou la façon de
penser des développeurs, sans qu'il y ait d'avantages réellement
déterminants, pour l'une ou l'autre.


Je pense que le choix dépend aussi du niveau d'abstarction des données
manipulées ainsi que de leur variété. Avec python, en particulier,
l'existance de dictionnaires donne beaucoup de potentiel à la
programmation structurée.

Dans les développements que j'ai effectué en python, j'ai souvent
commencé avec une programmation structurée pour passer à une
programmation objet. Ce qui m'a permis d'avoir des objets qui
correspondaient à mes besoins.

Xavier