Saltar al contenido

Cómo generar múltiples líneas en PDF usando Apache pdfbox

Nuestro team de trabajo ha estado mucho tiempo investigando para dar espuestas a tus búsquedas, te compartimos la respuestas por eso nuestro objetivo es serte de gran apoyo.

Solución:

Agregando a la respuesta de Mark, es posible que desee saber dónde dividir su largo string. Puedes usar el PDFont método getStringWidth para eso.

Al juntar todo, se obtiene algo como esto (con pequeñas diferencias según la versión de PDFBox):

PDFBox 1.8.x

PDDocument doc = null;
try

    doc = new PDDocument();
    PDPage page = new PDPage();
    doc.addPage(page);
    PDPageContentStream contentStream = new PDPageContentStream(doc, page);

    PDFont pdfFont = PDType1Font.HELVETICA;
    float fontSize = 25;
    float leading = 1.5f * fontSize;

    PDRectangle mediabox = page.findMediaBox();
    float margin = 72;
    float width = mediabox.getWidth() - 2*margin;
    float startX = mediabox.getLowerLeftX() + margin;
    float startY = mediabox.getUpperRightY() - margin;

    String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"; 
    List lines = new ArrayList();
    int lastSpace = -1;
    while (text.length() > 0)
    
        int spaceIndex = text.indexOf(' ', lastSpace + 1);
        if (spaceIndex < 0)
            spaceIndex = text.length();
        String subString = text.substring(0, spaceIndex);
        float size = fontSize * pdfFont.getStringWidth(subString) / 1000;
        System.out.printf("'%s' - %f of %fn", subString, size, width);
        if (size > width)
        
            if (lastSpace < 0)
                lastSpace = spaceIndex;
            subString = text.substring(0, lastSpace);
            lines.add(subString);
            text = text.substring(lastSpace).trim();
            System.out.printf("'%s' is linen", subString);
            lastSpace = -1;
        
        else if (spaceIndex == text.length())
        
            lines.add(text);
            System.out.printf("'%s' is linen", text);
            text = "";
        
        else
        
            lastSpace = spaceIndex;
        
    
        
    contentStream.beginText();
    contentStream.setFont(pdfFont, fontSize);
    contentStream.moveTextPositionByAmount(startX, startY);            
    for (String line: lines)
    
        contentStream.drawString(line);
        contentStream.moveTextPositionByAmount(0, -leading);
    
    contentStream.endText(); 
    contentStream.close();

    doc.save("break-long-string.pdf");

finally

    if (doc != null)
    
        doc.close();
    

(Prueba BreakLongString.java testBreakString para PDFBox 1.8.x)

PDFBox 2.0.x

PDDocument doc = null;
try

    doc = new PDDocument();
    PDPage page = new PDPage();
    doc.addPage(page);
    PDPageContentStream contentStream = new PDPageContentStream(doc, page);

    PDFont pdfFont = PDType1Font.HELVETICA;
    float fontSize = 25;
    float leading = 1.5f * fontSize;

    PDRectangle mediabox = page.getMediaBox();
    float margin = 72;
    float width = mediabox.getWidth() - 2*margin;
    float startX = mediabox.getLowerLeftX() + margin;
    float startY = mediabox.getUpperRightY() - margin;

    String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"; 
    List lines = new ArrayList();
    int lastSpace = -1;
    while (text.length() > 0)
    
        int spaceIndex = text.indexOf(' ', lastSpace + 1);
        if (spaceIndex < 0)
            spaceIndex = text.length();
        String subString = text.substring(0, spaceIndex);
        float size = fontSize * pdfFont.getStringWidth(subString) / 1000;
        System.out.printf("'%s' - %f of %fn", subString, size, width);
        if (size > width)
        
            if (lastSpace < 0)
                lastSpace = spaceIndex;
            subString = text.substring(0, lastSpace);
            lines.add(subString);
            text = text.substring(lastSpace).trim();
            System.out.printf("'%s' is linen", subString);
            lastSpace = -1;
        
        else if (spaceIndex == text.length())
        
            lines.add(text);
            System.out.printf("'%s' is linen", text);
            text = "";
        
        else
        
            lastSpace = spaceIndex;
        
    

    contentStream.beginText();
    contentStream.setFont(pdfFont, fontSize);
    contentStream.newLineAtOffset(startX, startY);
    for (String line: lines)
    
        contentStream.showText(line);
        contentStream.newLineAtOffset(0, -leading);
    
    contentStream.endText(); 
    contentStream.close();

    doc.save(new File(RESULT_FOLDER, "break-long-string.pdf"));

finally

    if (doc != null)
    
        doc.close();
    

(Prueba BreakLongString.java testBreakString para PDFBox 2.0.x)

El resultado

Captura de pantalla del PDF de resultados que se muestra en Acrobat Reader

Esto se ve como se esperaba.

Por supuesto, hay numerosas mejoras que hacer, pero esto debería mostrar cómo hacerlo.

Agregar saltos de línea incondicionales

En un comentario, aleskv preguntó:

¿Podría agregar saltos de línea cuando hay n en el string?

Uno puede extender fácilmente la solución para romper incondicionalmente en los caracteres de nueva línea dividiendo primero el string en caracteres ' n' y luego iterando sobre el resultado de la división.

Por ejemplo, si en lugar de la larga string desde arriba

String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"; 

quieres procesar esto aún más string con caracteres de nueva línea incrustados

String textNL = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox.nFurthermore, I have added some newline characters to the string at which lines also shall be broken.nIt should work alright like this...";

simplemente puedes reemplazar

String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"; 
List lines = new ArrayList();
int lastSpace = -1;
while (text.length() > 0)

    [...]

en las soluciones anteriores por

String textNL = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox.nFurthermore, I have added some newline characters to the string at which lines also shall be broken.nIt should work alright like this..."; 
List lines = new ArrayList();
for (String text : textNL.split("n"))

    int lastSpace = -1;
    while (text.length() > 0)
    
        [...]
    

(de la prueba BreakLongString.java testBreakStringNL)

El resultado:

Captura de pantalla

Sé que es un poco tarde, pero tuve un pequeño problema con la solución de mkl. Si la última línea solo contendría una palabra, su algoritmo la escribe en la anterior.

Por ejemplo: "Lorem ipsum dolor sit amet" es su texto y debe agregar un salto de línea después de "sentarse".

Lorem ipsum dolor sit
amet

Pero hace esto:

Lorem ipsum dolor sit amet

Se me ocurrió mi propia solución que quiero compartir con ustedes.

/**
 * @param text The text to write on the page.
 * @param x The position on the x-axis.
 * @param y The position on the y-axis.
 * @param allowedWidth The maximum allowed width of the whole text (e.g. the width of the page - a defined margin).
 * @param page The page for the text.
 * @param contentStream The content stream to set the text properties and write the text.
 * @param font The font used to write the text.
 * @param fontSize The font size used to write the text.
 * @param lineHeight The line height of the font (typically 1.2 * fontSize or 1.5 * fontSize).
 * @throws IOException
 */
private void drawMultiLineText(String text, int x, int y, int allowedWidth, PDPage page, PDPageContentStream contentStream, PDFont font, int fontSize, int lineHeight) throws IOException 

    List lines = new ArrayList();

    String myLine = "";

    // get all words from the text
    // keep in mind that words are separated by spaces -> "Lorem ipsum!!!!:)" -> words are "Lorem" and "ipsum!!!!:)"
    String[] words = text.split(" ");
    for(String word : words) 

        if(!myLine.isEmpty()) 
            myLine += " ";
        

        // test the width of the current line + the current word
        int size = (int) (fontSize * font.getStringWidth(myLine + word) / 1000);
        if(size > allowedWidth) 
            // if the line would be too long with the current word, add the line without the current word
            lines.add(myLine);

            // and start a new line with the current word
            myLine = word;
         else 
            // if the current line + the current word would fit, add the current word to the line
            myLine += word;
        
    
    // add the rest to lines
    lines.add(myLine);

    for(String line : lines) 
        contentStream.beginText();
        contentStream.setFont(font, fontSize);
        contentStream.moveTextPositionByAmount(x, y);
        contentStream.drawString(line);
        contentStream.endText();

        y -= lineHeight;
    


///// FOR PDBOX 2.0.X
//  FOR ADDING DYNAMIC PAGE ACCORDING THE LENGTH OF THE CONTENT

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

public class Document_Creation 

   public static void main (String args[]) throws IOException 

       PDDocument doc = null;
       try
       
           doc = new PDDocument();
           PDPage page = new PDPage();
           doc.addPage(page);
           PDPageContentStream contentStream = new PDPageContentStream(doc, page);

           PDFont pdfFont = PDType1Font.HELVETICA;
           float fontSize = 25;
           float leading = 1.5f * fontSize;

           PDRectangle mediabox = page.getMediaBox();
           float margin = 72;
           float width = mediabox.getWidth() - 2*margin;
           float startX = mediabox.getLowerLeftX() + margin;
           float startY = mediabox.getUpperRightY() - margin;

           String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox.An essay is, generally, a piece of writing that gives the author's own argument — but the definition is vague, overlapping with those of an article, a pamphlet, and a short story. Essays have traditionally been sub-classified as formal and informal. Formal essays are characterized by serious purpose, dignity, logical organization, length,whereas the informal essay is characterized by the personal element (self-revelation, individual tastes and experiences, confidential manner), humor, graceful style, rambling structure, unconventionality or novelty of theme.Lastly, one of the most attractive features of cats as housepets is their ease of care. Cats do not have to be walked. They get plenty of exercise in the house as they play, and they do their business in the litter box. Cleaning a litter box is a quick, painless procedure. Cats also take care of their own grooming. Bathing a cat is almost never necessary because under ordinary circumstances cats clean themselves. Cats are more particular about personal cleanliness than people are. In addition, cats can be left home alone for a few hours without fear. Unlike some pets, most cats will not destroy the furnishings when left alone. They are content to go about their usual activities until their owners return."; 
           List lines = new ArrayList();
           int lastSpace = -1;
           while (text.length() > 0)
           
               int spaceIndex = text.indexOf(' ', lastSpace + 1);
               if (spaceIndex < 0)
                   spaceIndex = text.length();
               String subString = text.substring(0, spaceIndex);
               float size = fontSize * pdfFont.getStringWidth(subString) / 1000;
               System.out.printf("'%s' - %f of %fn", subString, size, width);
               if (size > width)
               
                   if (lastSpace < 0)
                       lastSpace = spaceIndex;
                   subString = text.substring(0, lastSpace);
                   lines.add(subString);
                   text = text.substring(lastSpace).trim();
                   System.out.printf("'%s' is linen", subString);
                   lastSpace = -1;
               
               else if (spaceIndex == text.length())
               
                   lines.add(text);
                   System.out.printf("'%s' is linen", text);
                   text = "";
               
               else
               
                   lastSpace = spaceIndex;
               
           

           contentStream.beginText();
           contentStream.setFont(pdfFont, fontSize);
           contentStream.newLineAtOffset(startX, startY);
           float currentY=startY;
           for (String line: lines)
           
               currentY -=leading;

               if(currentY<=margin)
               

                   contentStream.endText(); 
                   contentStream.close();
                   PDPage new_Page = new PDPage();
                   doc.addPage(new_Page);
                   contentStream = new PDPageContentStream(doc, new_Page);
                   contentStream.beginText();
                   contentStream.setFont(pdfFont, fontSize);
                   contentStream.newLineAtOffset(startX, startY);
                   currentY=startY;
               
               contentStream.showText(line);
               contentStream.newLineAtOffset(0, -leading);
           
           contentStream.endText(); 
           contentStream.close();

           doc.save("C:/Users/VINAYAK/Desktop/docccc/break-long-string.pdf");
       
       finally
       
           if (doc != null)
           
               doc.close();
           
       

     

Producción

Valoraciones y reseñas

Más adelante puedes encontrar las notas de otros programadores, tú además puedes dejar el tuyo si te apetece.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *