Intégrer des tableaux PDF avec des sources de données en Java

L’exemple Java crée des tableaux PDF à partir de données CSV sans recourir à des bibliothèques de trames de données externes.

Construire un tableau à partir de lignes CSV

Utilisez cet exemple lorsque les colonnes CSV sélectionnées doivent être transformées en un tableau PDF stylisé.

  1. Créez une Table et configurez ses bordures.
  2. Détectez les index de colonnes requis à partir de la ligne d’en-tête CSV.
  3. Ajoutez la ligne d’en-tête et le nombre demandé de lignes de données, puis renvoyez le tableau.
public static Table createTableFromCsv(List<String[]> rows, int maxRows) {
    Table table = new Table();
    table.setBorder(new BorderInfo(BorderSide.All, 1, Color.getLightGray()));
    table.setDefaultCellBorder(new BorderInfo(BorderSide.Bottom, 1, Color.getLightGray()));

    String[] header = rows.get(0);
    int[] selectedColumns = findColumns(header, "city", "country", "population", "iso3");

    Row headerRow = table.getRows().add();
    headerRow.setRowBroken(false);
    for (int columnIndex : selectedColumns) {
        Cell cell = headerRow.getCells().add(header[columnIndex]);
        cell.setBackgroundColor(Color.getLightGray());
    }

    int limit = Math.min(maxRows, rows.size() - 1);
    for (int rowIndex = 1; rowIndex <= limit; rowIndex++) {
        Row row = table.getRows().add();
        String[] rowData = rows.get(rowIndex);
        for (int columnIndex : selectedColumns) {
            row.getCells().add(columnIndex < rowData.length ? rowData[columnIndex] : "");
        }
    }

    return table;
}

Créer un PDF à partir de données CSV

Utilisez cet exemple lorsque l’entrée CSV doit être restituée sous forme de document tableau PDF.

  1. Lisez les lignes CSV du fichier d’entrée.
  2. Prévisualisez un sous-ensemble des lignes analysées dans la console.
  3. Créez un document PDF Document, ajoutez le tableau généré et enregistrez le fichier de sortie.
public static void createPdfFromCsv(Path inputFile, Path outputFile, int maxRows) throws Exception {
    List<String[]> rows = readCsv(inputFile);
    for (int i = 0; i < Math.min(20, rows.size()); i++) {
        System.out.println(String.join(" | ", rows.get(i)));
    }

    try (Document document = new Document()) {
        Page page = document.getPages().add();
        page.getParagraphs().add(createTableFromCsv(rows, maxRows));
        document.save(outputFile.toString());
    }
}

Rechercher les index de colonnes CSV par nom

Utilisez cette méthode auxiliaire lorsque des colonnes nommées spécifiques doivent être situées dans la ligne d’en-tête CSV.

  1. Parcourez les noms de colonnes demandés.
  2. Recherchez dans la ligne d’en-tête les index correspondants.
  3. Renvoie les positions des colonnes collectées.
private static int[] findColumns(String[] header, String... names) {
    int[] indexes = new int[names.length];
    for (int i = 0; i < names.length; i++) {
        indexes[i] = 0;
        for (int j = 0; j < header.length; j++) {
            if (names[i].equals(header[j])) {
                indexes[i] = j;
                break;
            }
        }
    }
    return indexes;
}

Lire les lignes CSV d’un fichier

Utilisez cette méthode auxiliaire lorsque la source CSV doit être chargée en mémoire avant la génération du tableau.

  1. Lisez toutes les lignes du fichier d’entrée.
  2. Divisez chaque ligne avec l’assistant de l’analyseur CSV.
  3. Renvoie les valeurs de ligne collectées.
private static List<String[]> readCsv(Path inputFile) throws Exception {
    List<String[]> rows = new ArrayList<>();
    for (String line : Files.readAllLines(inputFile)) {
        rows.add(splitCsvLine(line));
    }
    return rows;
}

Diviser une ligne CSV en valeurs

Utilisez cet assistant lorsqu’une ligne CSV peut contenir des valeurs entre guillemets et des guillemets d’échappement.

  1. Parcourez les caractères de la ligne.
  2. Vérifiez si l’analyseur se trouve actuellement dans le texte cité.
  3. Créez la liste de valeurs finale et renvoyez-la sous forme de tableau.
private static String[] splitCsvLine(String line) {
    List<String> values = new ArrayList<>();
    StringBuilder current = new StringBuilder();
    boolean inQuotes = false;
    for (int i = 0; i < line.length(); i++) {
        char ch = line.charAt(i);
        if (ch == '"') {
            if (inQuotes && i + 1 < line.length() && line.charAt(i + 1) == '"') {
                current.append('"');
                i++;
            } else {
                inQuotes = !inQuotes;
            }
        } else if (ch == ',' && !inQuotes) {
            values.add(current.toString());
            current.setLength(0);
        } else {
            current.append(ch);
        }
    }
    values.add(current.toString());
    return values.toArray(String[]::new);
}