OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 156 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
41 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
182 ilm 4
 * Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
41 ilm 5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.erp.generationDoc;
15
 
16
import org.openconcerto.erp.config.ComptaPropsConfiguration;
17
import org.openconcerto.erp.core.common.element.StyleSQLElement;
18
import org.openconcerto.openoffice.ODPackage;
19
import org.openconcerto.openoffice.spreadsheet.MutableCell;
20
import org.openconcerto.openoffice.spreadsheet.Sheet;
21
import org.openconcerto.openoffice.spreadsheet.SpreadSheet;
22
import org.openconcerto.openoffice.spreadsheet.Table;
23
import org.openconcerto.sql.Configuration;
24
import org.openconcerto.sql.model.SQLRow;
25
import org.openconcerto.utils.ExceptionHandler;
26
import org.openconcerto.utils.StreamUtils;
156 ilm 27
import org.openconcerto.utils.io.BOMSkipper;
41 ilm 28
 
29
import java.awt.Point;
156 ilm 30
import java.io.BufferedReader;
41 ilm 31
import java.io.File;
32
import java.io.FileNotFoundException;
33
import java.io.IOException;
34
import java.io.InputStream;
156 ilm 35
import java.io.InputStreamReader;
36
import java.nio.charset.Charset;
41 ilm 37
import java.util.HashMap;
38
import java.util.Iterator;
39
import java.util.List;
40
import java.util.Map;
41
 
42
import javax.swing.JOptionPane;
43
import javax.swing.SwingUtilities;
44
 
132 ilm 45
import org.jdom2.Document;
46
import org.jdom2.Element;
47
import org.jdom2.JDOMException;
48
import org.jdom2.input.SAXBuilder;
41 ilm 49
 
50
public class OOgenerationListeColumnXML {
51
 
52
    // Cache pour la recherche des styles
156 ilm 53
    private static Map<Sheet, Map<String, Map<Integer, String>>> cacheStyle = new HashMap<>();
41 ilm 54
 
55
    public static File genere(String modele, File pathDest, String fileDest, Map<Integer, List<Map<String, Object>>> liste, Map<Integer, Map<String, Object>> values) {
56
        return genere(modele, pathDest, fileDest, liste, values, new HashMap<Integer, Map<Integer, String>>(), null, null);
57
    }
58
 
59
    public static File genere(String templateId, File pathDest, String fileDest, Map<Integer, List<Map<String, Object>>> liste, Map<Integer, Map<String, Object>> values,
60
            Map<Integer, Map<Integer, String>> mapStyle, List<String> sheetName, SQLRow rowLanguage) {
61
        cacheStyle.clear();
62
        final SAXBuilder builder = new SAXBuilder();
63
        try {
64
            InputStream xmlConfiguration = TemplateManager.getInstance().getTemplateConfiguration(templateId, rowLanguage != null ? rowLanguage.getString("CHEMIN") : null, null);
149 ilm 65
            if (xmlConfiguration == null) {
66
                throw new IllegalStateException("Template configuration " + templateId + " not found (" + TemplateManager.getInstance().getClass().getName() + ")");
67
            }
156 ilm 68
            final BufferedReader xmlConfigurationReader = new BufferedReader(new InputStreamReader(xmlConfiguration, Charset.forName("UTF8")));
69
            BOMSkipper.skip(xmlConfigurationReader);
70
            final Document doc = builder.build(xmlConfigurationReader);
71
            xmlConfigurationReader.close();
72
            xmlConfiguration.close();
41 ilm 73
 
74
            // On initialise un nouvel élément racine avec l'élément racine du
75
            // document.
76
            final Element racine = doc.getRootElement();
77
 
78
            // Création et génération du fichier OO
79
            final InputStream template = TemplateManager.getInstance().getTemplate(templateId, rowLanguage != null ? rowLanguage.getString("CHEMIN") : null, null);
149 ilm 80
            if (template == null) {
81
                throw new IllegalStateException("Template " + templateId + " not found (" + TemplateManager.getInstance().getClass().getName() + ")");
82
            }
41 ilm 83
            final SpreadSheet spreadSheet = new ODPackage(template).getSpreadSheet();
84
            Sheet sheet0 = spreadSheet.getSheet(0);
85
            if (sheetName != null && sheetName.size() > 0) {
86
                for (int i = 1; i < sheetName.size(); i++) {
87
                    sheet0.copy(i, (sheetName != null) ? sheetName.get(i) : "Feuille " + i);
88
                }
89
                spreadSheet.getSheet(0).setName(sheetName.get(0));
90
            }
91
 
92
            for (Integer i : liste.keySet()) {
93
                final Sheet sheet = spreadSheet.getSheet(i);
94
                List children = racine.getChildren("element" + i);
156 ilm 95
                if (children.isEmpty()) {
41 ilm 96
                    children = racine.getChildren("element");
97
                }
98
                parseElementsXML(children, sheet, values.get(i));
99
                Element child = racine.getChild("table" + i);
100
                if (child == null) {
101
                    child = racine.getChild("table");
102
                }
103
                parseListeXML(child, liste.get(i), sheet, mapStyle.get(i));
104
            }
105
            // Sauvegarde du fichier
106
            return saveSpreadSheet(spreadSheet, pathDest, fileDest, templateId, rowLanguage);
107
 
108
        } catch (JDOMException e) {
109
            ExceptionHandler.handle("Erreur lors de la génération du fichier " + fileDest, e);
110
        } catch (IOException e) {
111
            ExceptionHandler.handle("Erreur lors de la création du fichier " + fileDest, e);
112
        }
113
        return null;
114
    }
115
 
116
    private static void parseElementsXML(List<Element> elts, Sheet sheet, Map<String, Object> values) {
117
        if (values == null) {
118
            return;
119
        }
120
        for (Element elt : elts) {
121
 
122
            String name = elt.getAttributeValue("ValueName");
123
            Object result = values.get(name);
124
 
125
            if (result != null) {
126
                boolean controlLine = elt.getAttributeValue("controleMultiline") == null ? true : !elt.getAttributeValue("controleMultiline").equalsIgnoreCase("false");
127
                boolean replace = elt.getAttributeValue("type").equalsIgnoreCase("Replace");
128
                String replacePattern = elt.getAttributeValue("replacePattern");
129
                fill(sheet.getCellAt(elt.getAttributeValue("location")), result, sheet, replace, replacePattern, null, false, controlLine);
130
            }
131
        }
132
    }
133
 
134
    /**
135
     * Remplit le tableau
136
     *
137
     * @param tableau
138
     * @param elt
139
     * @param id
140
     * @param sheet
141
     */
142
    private static void parseListeXML(Element tableau, List<Map<String, Object>> liste, Sheet sheet, Map<Integer, String> style) {
143
 
144
        if (liste == null || tableau == null) {
145
            return;
146
        }
147
        Object oLastColTmp = tableau.getAttributeValue("lastColumn");
148
        int lastColumn = -1;
156 ilm 149
        int endPageLine = Integer.parseInt(tableau.getAttributeValue("endPageLine"));
41 ilm 150
        if (oLastColTmp != null) {
151
            lastColumn = sheet.resolveHint(oLastColTmp.toString() + 1).x + 1;
152
        }
153
        Map<String, Map<Integer, String>> mapStyle = searchStyle(sheet, lastColumn, endPageLine);
182 ilm 154
 
41 ilm 155
        fillTable(tableau, liste, sheet, mapStyle, false, style);
182 ilm 156
 
41 ilm 157
    }
158
 
159
    /**
160
     * Remplit le tableau d'éléments avec les données
161
     *
162
     * @param tableau Element Xml contenant les informations sur le tableau
163
     * @param elt SQLElement (ex : Bon de livraison)
164
     * @param id id de l'élément de la table
165
     * @param sheet feuille calc à remplir
166
     * @param mapStyle styles trouvés dans la page
167
     * @param test remplir ou non avec les valeurs
168
     * @return le nombre de page
169
     */
170
    private static int fillTable(Element tableau, List<Map<String, Object>> liste, Sheet sheet, Map<String, Map<Integer, String>> mapStyle, boolean test, Map<Integer, String> style) {
171
 
156 ilm 172
        int endLine = Integer.parseInt(tableau.getAttributeValue("endLine"));
41 ilm 173
 
174
        List listElts = tableau.getChildren("element");
175
 
176
        Object o = null;
142 ilm 177
        // String columnSousTotal = tableau.getAttributeValue("groupSousTotalColumn");
178
        //
179
        // Map<String, Double> mapSousTotal = new HashMap<String, Double>();
180
        // Map<String, Double> mapTotal = new HashMap<String, Double>();
41 ilm 181
 
182
        // on remplit chaque colonnes à partir des rows recuperées
183
        sheet.setColumnCount(liste.size() + 5);
184
        Integer firstCol = Integer.valueOf(tableau.getAttributeValue("firstLine"));
185
        int currentCol = firstCol;
186
        for (int i = 0; i < liste.size(); i++) {
187
            Map<String, Object> mValues = liste.get(i);
188
            if (currentCol != firstCol) {
189
                for (int k = 0; k < endLine; k++) {
190
                    MutableCell<SpreadSheet> c1 = sheet.getCellAt(firstCol, k);
191
                    if (c1.getFormula() != null && c1.getFormula().trim().length() > 0) {
192
                        String formula = c1.getFormula();
193
                        MutableCell<SpreadSheet> c2 = sheet.getCellAt(currentCol, k);
194
                        System.err.println(formula);
195
                        formula = formula.replaceAll("(" + Table.toStr(c1.getX()) + ")" + "(\\d+)", Table.toStr(c2.getX()) + "$2");
196
                        formula = formula.replaceAll(Table.toStr(c1.getX()) + "\\$", Table.toStr(c2.getX()) + "\\$");
197
                        System.err.println(" replace by " + formula);
198
                        c2.getElement().setAttribute("formula", formula, c2.getElement().getNamespace());
199
                        c2.setStyleName(c1.getStyleName());
200
                    }
201
                }
202
            }
203
 
204
            String styleName = null;
205
            // int nbCellule = 1;
206
            // on remplit chaque cellule de la colonne
207
            for (Iterator j = listElts.iterator(); j.hasNext();) {
208
 
209
                // if ((currentLine - 1 + fill("A1", "test", sheet, false, null, null, true)) >
210
                // (endPageLine * nbPage)) {
211
                // currentLine = currentLineTmp + endPageLine;
212
                // currentLineTmp = currentLine;
213
                // nbPage++;
214
                // }
215
 
216
                Element e = (Element) j.next();
217
                MutableCell<SpreadSheet> cell = sheet.getCellAt(currentCol, Integer.valueOf(e.getAttributeValue("location").trim()));
218
                // String loc = e.getAttributeValue("location").trim() + currentLine;
219
                boolean controlLine = e.getAttributeValue("controleMultiline") == null ? true : !e.getAttributeValue("controleMultiline").equalsIgnoreCase("false");
220
                // Type normaux fill ou replace
221
                if (e.getAttributeValue("type").equalsIgnoreCase("fill") || e.getAttributeValue("type").equalsIgnoreCase("replace")) {
222
 
223
                    Object value = getElementValue(e, mValues);
224
 
225
                    boolean replace = e.getAttributeValue("type").equalsIgnoreCase("replace");
226
 
227
                    if (test || cell.isValid()) {
228
                        // if (style != null) {
229
                        // styleName = style.get(i);
230
                        // }
231
                        // Map mTmp = styleName == null ? null : (Map) mapStyle.get(styleName);
232
                        // String styleOO = null;
233
                        // if (mTmp != null) {
234
                        //
235
                        // Object oTmp = mTmp.get(new Integer(sheet.resolveHint(loc).x));
236
                        // styleOO = oTmp == null ? null : oTmp.toString();
237
                        // System.err.println("Set style " + styleOO);
238
                        // }
239
                        if (currentCol != firstCol) {
240
                            MutableCell<SpreadSheet> c2 = sheet.getCellAt(firstCol, cell.getPoint().y);
241
                            styleName = c2.getStyleName();
242
                        }
243
                        int tmpCelluleAffect = fill(cell, value, sheet, replace, null, styleName, test, controlLine);
244
                        // nbCellule = Math.max(nbCellule, tmpCelluleAffect);
245
                    } else {
246
                        System.err.println("Cell not valid at " + cell);
247
                    }
248
                }
249
            }
250
            // currentLine += nbCellule;
251
            currentCol++;
252
 
253
        }
254
 
255
        return 1;
256
    }
257
 
258
    private static void incrementTotal(String field, Double value, Map<String, Double> map) {
259
        Double d = map.get(field);
260
        if (d == null) {
261
            map.put(field, value);
262
        } else {
263
            map.put(field, d + value);
264
        }
265
    }
266
 
267
    private static Object getElementValue(Element elt, Map<String, Object> mValues) {
268
        Object res = "";
269
 
270
        final List eltFields = elt.getChildren("field");
271
 
272
        if (eltFields != null) {
273
            if (eltFields.size() > 1) {
274
                String result = "";
275
                for (Iterator j = eltFields.iterator(); j.hasNext();) {
276
                    Object o = getValueOfComposant((Element) j.next(), mValues);
277
                    if (o != null) {
278
                        result += o.toString() + " ";
279
                    }
280
                }
281
                res = result;
282
            } else {
283
                res = getValueOfComposant((Element) eltFields.get(0), mValues);
284
            }
285
        }
286
        return res;
287
    }
288
 
289
    /**
290
     * permet d'obtenir la valeur d'un élément field
291
     *
292
     * @param eltField
293
     * @param row
294
     * @param elt
295
     * @param id
296
     * @return value of composant
297
     */
298
    private static Object getValueOfComposant(Element eltField, Map<String, Object> mValues) {
299
 
300
        String field = eltField.getAttributeValue("name");
301
 
302
        return mValues.get(field);
303
    }
304
 
305
    private static int fill(String location, Object value, Sheet sheet, boolean replace, String replacePattern, String styleOO, boolean test) {
306
        return fill(sheet.getCellAt(location), value, sheet, replace, replacePattern, styleOO, test, true);
307
    }
308
 
309
    /**
310
     * Permet de remplir une cellule
311
     *
312
     * @param location position de la cellule exemple : A3
313
     * @param value valeur à insérer dans la cellule
314
     * @param sheet feuille sur laquelle on travaille
315
     * @param replace efface ou non le contenu original de la cellule
316
     * @param styleOO style à appliquer
317
     */
318
    private static int fill(MutableCell<SpreadSheet> cell, Object value, Sheet sheet, boolean replace, String replacePattern, String styleOO, boolean test, boolean controlLine) {
319
 
320
        int nbCellule = 1;
321
        // est ce que la cellule est valide
322
        if (test || cell.isValid()) {
323
 
324
            // on divise en 2 cellules si il y a des retours à la ligne
325
            if (controlLine && (value != null && value.toString().indexOf('\n') >= 0)) {
326
 
327
                if (!test) {
328
                    String firstPart = value.toString().substring(0, value.toString().indexOf('\n'));
329
                    String secondPart = value.toString().substring(value.toString().indexOf('\n') + 1, value.toString().length());
330
                    secondPart = secondPart.replace('\n', ',');
331
                    setCellValue(cell, firstPart, replace, replacePattern);
332
                    if (styleOO != null) {
333
                        cell.setStyleName(styleOO);
334
                    }
335
 
336
                    // Point p = sheet.resolveHint(location);
337
                    Point p = cell.getPoint();
338
                    try {
339
                        MutableCell cellSec = sheet.getCellAt(p.x, p.y + 1);
340
                        setCellValue(cellSec, secondPart, replace, replacePattern);
341
                    } catch (Exception ex) {
342
                        ex.printStackTrace();
343
                    }
344
                }
345
                nbCellule = 2;
346
            } else {
347
                if (!test) {
348
                    // application de la valeur
349
                    setCellValue(cell, value, replace, replacePattern);
350
 
351
                    // Application du style
352
                    if (styleOO != null) {
353
                        cell.setStyleName(styleOO);
354
                    }
355
                }
356
            }
357
        }
358
        return nbCellule;
359
    }
360
 
361
    /**
362
     * remplit une cellule
363
     *
364
     * @param cell
365
     * @param value
366
     * @param replace
367
     */
368
    private static void setCellValue(MutableCell cell, Object value, boolean replace, String replacePattern) {
369
        if (value == null) {
370
            value = "";
371
        }
372
 
373
        if (replace) {
374
            if (replacePattern != null) {
375
                cell.replaceBy(replacePattern, value.toString());
376
            } else {
377
                cell.replaceBy("_", value.toString());
378
            }
379
        } else {
380
            cell.setValue(value);
381
        }
382
    }
383
 
384
    /**
385
     * Sauver le document au format OpenOffice. Si le fichier existe déjà, le fichier existant sera
386
     * renommé sous la forme nomFic_1.sxc.
387
     *
388
     * @param ssheet SpreadSheet à sauvegarder
389
     * @param pathDest répertoire de destination du fichier
390
     * @param fileName nom du fichier à créer
391
     * @return un File pointant sur le fichier créé
392
     * @throws IOException
393
     */
394
    private static File saveSpreadSheet(SpreadSheet ssheet, File pathDest, String fileName, String templateId, SQLRow rowLanguage) throws IOException {
395
 
396
        // Test des arguments
397
        if (ssheet == null || pathDest == null || fileName.trim().length() == 0) {
398
            throw new IllegalArgumentException();
399
        }
400
 
401
        // Renommage du fichier si il existe déja
402
        File fDest = new File(pathDest, fileName + ".ods");
403
 
404
        if (!pathDest.exists()) {
405
            pathDest.mkdirs();
406
        }
407
 
57 ilm 408
        SheetUtils.convertToOldFile(((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete(), fileName, pathDest, fDest);
41 ilm 409
 
410
        // Sauvegarde
411
        try {
412
            ssheet.saveAs(fDest);
413
        } catch (FileNotFoundException e) {
414
            final File F = fDest;
415
            SwingUtilities.invokeLater(new Runnable() {
416
                public void run() {
417
                    try {
418
                        JOptionPane.showMessageDialog(null, "Le fichier " + F.getCanonicalPath() + " n'a pu être créé. \n Vérifiez qu'il n'est pas déjà ouvert.");
419
                    } catch (IOException e) {
420
                        e.printStackTrace();
421
                    }
422
                }
423
            });
424
 
425
            e.printStackTrace();
426
        }
427
 
428
        // Copie de l'odsp
156 ilm 429
        File odspOut = new File(pathDest, fileName + ".odsp");
430
        try (final InputStream odspIn = TemplateManager.getInstance().getTemplatePrintConfiguration(templateId, rowLanguage != null ? rowLanguage.getString("CHEMIN") : null, null);) {
41 ilm 431
            if (odspIn != null) {
432
                StreamUtils.copy(odspIn, odspOut);
433
            }
434
        } catch (FileNotFoundException e) {
435
            System.err.println("Le fichier odsp n'existe pas.");
436
        }
437
 
438
        return fDest;
439
    }
440
 
441
    /**
442
     * parcourt l'ensemble de la feuille pour trouver les style définit
443
     */
444
    private static Map<String, Map<Integer, String>> searchStyle(Sheet sheet, int colEnd, int rowEnd) {
445
 
446
        if (cacheStyle.get(sheet) != null) {
447
            return cacheStyle.get(sheet);
448
        }
449
 
450
        Map<String, Map<Integer, String>> mapStyleDef = StyleSQLElement.getMapAllStyle();
451
 
452
        // on parcourt chaque ligne de la feuille pour recuperer les styles
453
        int columnCount = (colEnd == -1) ? sheet.getColumnCount() : (colEnd + 1);
454
        System.err.println("End column search : " + columnCount);
455
 
456
        int rowCount = (rowEnd > 0) ? rowEnd : sheet.getRowCount();
457
        System.err.println("End row search : " + rowCount);
458
        for (int i = 0; i < rowCount; i++) {
459
            int x = 0;
460
            Map<Integer, String> mapCellStyle = new HashMap<Integer, String>();
461
            String style = "";
462
 
463
            for (int j = 0; j < columnCount; j++) {
464
 
465
                try {
466
                    if (sheet.isCellValid(j, i)) {
467
 
468
                        MutableCell c = sheet.getCellAt(j, i);
469
                        String cellStyle = c.getStyleName();
470
 
471
                        try {
472
                            if (mapStyleDef.containsKey(c.getValue().toString())) {
473
                                style = c.getValue().toString();
474
                                // System.err.println("FIND STYLE " +
475
                                // c.getValue().toString() +
476
                                // " SET VALUE " + cellStyle);
477
                            }
478
                        } catch (IllegalStateException e) {
479
                            e.printStackTrace();
480
                        }
481
                        mapCellStyle.put(Integer.valueOf(x), cellStyle);
482
                        if (style.trim().length() != 0) {
483
                            c.clearValue();
484
                            // c.setStyle("Default");
485
                            if (!style.trim().equalsIgnoreCase("Normal") && mapStyleDef.get("Normal") != null) {
486
                                String styleCell = mapStyleDef.get("Normal").get(Integer.valueOf(x));
487
                                if (styleCell != null && styleCell.length() != 0) {
488
                                    c.setStyleName(styleCell);
489
                                }
490
                            }
491
                        }
492
                    }
493
                } catch (IndexOutOfBoundsException e) {
494
                    System.err.println("Index out of bounds Exception");
495
                }
496
                x++;
497
            }
498
 
499
            if (style.length() > 0) {
500
                mapStyleDef.put(style, mapCellStyle);
501
                // System.err.println("style " + mapCellStyle);
502
            }
503
        }
504
        cacheStyle.put(sheet, mapStyleDef);
505
        return mapStyleDef;
506
    }
507
 
508
    public static void main(String[] args) {
509
        ComptaPropsConfiguration conf = ComptaPropsConfiguration.create();
510
        System.err.println("Conf created");
511
        Configuration.setInstance(conf);
512
        conf.setUpSocieteDataBaseConnexion(36);
513
        System.err.println("Connection Set up");
514
 
515
        System.err.println("Start Genere");
516
        // genere("Devis", "C:\\", "Test", elt, 19);
517
        System.err.println("Stop genere");
518
    }
519
}