2011-09-29 10 views
6

Devo creare un PDF con una tabella. Finora funziona bene, ma ora voglio aggiungere una funzionalità di avvolgimento. Quindi ho bisogno di inserire un avanzamento di riga.Come inserire un avanzamento di riga con PDFBox drawString

contentStream.beginText(); 
contentStream.moveTextPositionByAmount(x, y); 
contentStream.drawString("Some text to insert into a table."); 
contentStream.endText(); 

voglio aggiungere un "\n" prima "insert". Ho provato "\u000A" che è il valore esadecimale per il linefeed, ma Eclipse mi mostra un errore.

E 'possibile aggiungere linefeed con drawString?

risposta

8

Il formato PDF non conosce le interruzioni di riga. Devi dividere la stringa e spostare la posizione del testo sulla riga successiva, usando moveTextPositionByAmount.

Questa non è una funzione speciale "pdfbox", è dovuta alla definizione del formato pdf; quindi non c'è modo per drawString e non ci sono altri metodi per essere chiamati a supportare i linefeed.

+1

@Erik: Ma che cosa è con 'T *' - e '' '-operator? specifica PDF dice a T *: "Sposta all'inizio della riga successiva". E a ': "Passa alla riga successiva e mostra una stringa di testo". Ma non sono riuscito a trovare un modo per usare T * o 'in pdfBox. (E non sono sicuro di aver capito le specifiche corrette o meno). – Lukas

0

Poiché il modello PDF spesso non è il miglior modello per l'attività in corso, ha spesso senso scrivere un wrapper per esso che aggiunge il supporto per qualsiasi cosa "mancante" nel tuo caso. Questo è vero sia per la lettura che per la scrittura.

12

Il formato PDF consente interruzioni di riga, ma PDFBox non ha funzionalità incorporate per interruzioni di riga.

Per utilizzare le interruzioni di riga in PDF, è necessario definire l'interlinea che si desidera utilizzare con il TL -operator. Il T* -operator effettua un'interruzione di riga. Il ' -operator scrive il testo specificato nella riga successiva. (Vedi le specifiche PDF per ulteriori dettagli, capitolo "Testo". Non è molto.)

Ecco alcuni frammenti di codice. Entrambi fanno lo stesso, ma il primo frammento utilizza ' e il secondo frammento utilizza T*.

private void printMultipleLines(
    PDPageContentStream contentStream, 
    List<String> lines, 
    float x, 
    float y) throws IOException { 
    if (lines.size() == 0) { 
    return; 
    } 
    final int numberOfLines = lines.size(); 
    final float fontHeight = getFontHeight(); 

    contentStream.beginText(); 
    contentStream.appendRawCommands(fontHeight + " TL\n"); 
    contentStream.moveTextPositionByAmount(x, y); 
    contentStream.drawString(lines.get(0)); 
    for (int i = 1; i < numberOfLines; i++) { 
    contentStream.appendRawCommands(escapeString(lines.get(i))); 
    contentStream.appendRawCommands(" \'\n"); 
    } 
    contentStream.endText(); 
} 

private String escapeString(String text) throws IOException { 
    try { 
    COSString string = new COSString(text); 
    ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 
    string.writePDF(buffer); 
    return new String(buffer.toByteArray(), "ISO-8859-1"); 
    } catch (UnsupportedEncodingException e) { 
    // every JVM must know ISO-8859-1 
    throw new RuntimeException(e); 
    } 
} 

Usa T* per interruzione di linea:

private void printMultipleLines(
    PDPageContentStream contentStream, 
    List<String> lines, 
    float x, 
    float y) throws IOException { 
    if (lines.size() == 0) { 
    return; 
    } 
    final int numberOfLines = lines.size(); 
    final float fontHeight = getFontHeight(); 

    contentStream.beginText(); 
    contentStream.appendRawCommands(fontHeight + " TL\n"); 
    contentStream.moveTextPositionByAmount(x, y); 
    for (int i = 0; i < numberOfLines; i++) { 
    contentStream.drawString(lines.get(i)); 
    if (i < numberOfLines - 1) { 
     contentStream.appendRawCommands("T*\n"); 
    } 
    } 
    contentStream.endText(); 
} 

per ottenere l'altezza del carattere è possibile utilizzare questo comando:

fontHeight = font.getFontDescriptor().getFontBoundingBox().getHeight()/1000 * fontSize; 

Si potrebbe desiderare di moltiplicarlo briciolo qualche passo della linea fattore.