Bonjour
Pour un besoin en interne, j'ai créé sur mon Windows un serveur Datasnap pour convertir des documents.
Il s'agit principalement de convertir un docx en pdf.
Le serveur reçoit le contenu du fichier source en base64 (envoyé par un site en PHP sur une VM linux).
Il le décode et l'enregistre sur disque dans %temp%.
Puis, je crée une instance de Word, je lui fais ouvrir le fichier et j'utilise SaveAs pour le convertir en pdf.
Je referme Word et je charge le document pour le renvoyer au script PHP appelant qui décode le tout et l’affiche ou l'enregistre.
Tout ça fonctionne très bien à un détail près. Ça prend beaucoup trop de temps.
J'ai chronométré les phases d'exécution et je trouve en moyenne:
- Instance Word créée en: 2000 ms
- Document chargé en: 547 ms
- Conversion terminée en: 4735 ms
Pour le code, il est des plus simples:
J'ai essayé une solution consistant à créer le serveur au démarrage de l'appli mais chaque appel au "service WEB" étant threadé, ça ne fonctionne pas (ou tout au moins, je n'ai pas réussi).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 function InnerConvertDocxToPDF(var ContentFileToConvert: string): Boolean; var Word: Word_TLB._Application; Document: Word_TLB._Document; Unknown: IUnknown; T: Cardinal; begin T := GetTickCount; if (GetActiveObject(Word_TLB.CLASS_WordApplication, nil, Unknown) = MK_E_UNAVAILABLE) then Word := Word_TLB.CoWordApplication.Create; Word.Visible := False; Log('Instance Word créée en: ' + (GetTickCount - T).ToString); try try T := GetTickCount; Document := Word.Documents.Open(ContentFileToConvert, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam); Log('Document chargé en: ' + (GetTickCount - T).ToString); ContentFileToConvert := ChangeFileExt(ContentFileToConvert, '.pdf'); T := GetTickCount; Document.SaveAs2(ContentFileToConvert, Word_TLB.wdFormatPDF, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam); Log('Conversion terminée en: ' + (GetTickCount - T).ToString); Document.Close(EmptyParam,EmptyParam,EmptyParam); Result := True; except on E: Exception do Result := False; end; finally Word.Quit(False, EmptyParam, EmptyParam); Word := nil; end; end;
Est-ce que vous voyez une solution, qui me permettrait d'accélerer un peu le processus ?
Evidemment, si je pouvais créer mon instance de word une fois pour toute, je gagnerais déjà 2 secondes à chaque fois, ce qui serait déjà un gros mieux
En question subsidiaire, j'ai du rater un truc sur COM.
Même si j'ai un word ouvert sur mon poste, GetActiveObject ne le trouve pas et en crée un autre.
Est-ce normal ???
Partager