¿Cómo crear archivos PDF en una aplicación de Android? [cerrado]

147

¿Hay alguna forma de crear archivos PDF desde una aplicación de Android?

hichris123
fuente
66
¿No sería bueno si el modelo de imagen de Android se inspirara en Qt's? Qt estableció que generar PDF o SVG puede ser tan simple como redirigir el mismo código que uno usa para dibujar en la pantalla. Mire la derivación de QPrinter, QSvgGenerator y QWidget de QPaintDevice para el patrón.
Calaf
1
Lo mismo en iOS. La generación de PDF está incorporada.
Fabian Zeindl
2
Creo que Kit Kat tiene una función para generar PDF, pero no sé si esto es compatible con versiones anteriores. He publicado una opción a continuación y el siguiente sitio enumera varias opciones que van desde comerciales a gratuitas: stefan.fenz.at/creating-pdfs-on-android-an-evaluation
IcedDante
55
Ridículo que esto se cerró como "fuera de tema".
Joe Coder
2
¿Por qué se cerró esta publicación? Stackoverflow es demasiado exigente con su alcance; esta pregunta tiene 175,000 visitas, como un recurso de codificación este sitio debería permitir cosas hipercomunes como esta, las reglas necesitan enmendarse, leemos demasiado lejos en el texto literal de lo que está "fuera de tema" en lugar del núcleo de la regla. Lo marqué para volver a abrir, espero que otros también voten.
Albert Renshaw

Respuestas:

155

Si alguien quiere generar archivos PDF en un dispositivo Android, aquí está cómo hacerlo:

nikib3ro
fuente
54
El único problema con iText es que es una licencia GPLv3, o de lo contrario debe comprar una licencia comercial.
Tony Maro
55
y versiones anteriores de iText tienen algunas dependencias faltantes como java.awt.Color que dalvik no admite
k-deux
3
@ kape123 buen sentido del humor :-)
AZ_
10
La respuesta derrotista genérica de CommonsWare ... pwned.
moonlightcheese
2
la licencia comercial cuesta aproximadamente USD 0,50 (0,42 EUR) por dispositivo Android. (11-2013)
Chris623
104

Si está desarrollando dispositivos con un nivel de API 19 o superior, puede usar el documento impreso PrintedPdf: http://developer.android.com/reference/android/print/pdf/PrintedPdfDocument.html

// open a new document
PrintedPdfDocument document = new PrintedPdfDocument(context,
     printAttributes);

// start a page
Page page = document.startPage(0);

// draw something on the page
View content = getContentView();
content.draw(page.getCanvas());

// finish the page
document.finishPage(page);
. . .
// add more pages
. . .
// write the document content
document.writeTo(getOutputStream());

//close the document
document.close();
teh.fonsi
fuente
2
Finalmente es parte de Android como parte de iOS.
lalitm
55
@ Chris623 Creo que te referías a "KitKat" ... :)
desarrollador de Android
77
@lalitm No es como es en ios. El PDF generado en iOS tiene texto seleccionable escrito en doc. Pero en Android es una imagen.
Kantesh
2
@WillThomson ¿Se suponía que tu enlace de GitHub era este u otro?
jk7
3
Muchas gracias, el enlace útil está aquí github.com/IanDarwin/Android-Cookbook-Examples/blob/master/…
Kibi
27

Un truco para hacer un PDF con características complejas es hacer una actividad ficticia con el diseño xml deseado. Luego puede abrir esta actividad ficticia, tomar una captura de pantalla mediante programación y convertir esa imagen a pdf usando esta biblioteca . Por supuesto, hay limitaciones, como no poder desplazarse, no más de una página, pero para una aplicación limitada, esto es rápido y fácil. ¡Espero que esto ayude a alguien!

hrishitiwari
fuente
2
Merecía al menos 1up.
Rahul Rastogi
trabajó para mi. Fue una implementación simple.
TharakaNirmana
esa es una solución genial
Kumar Saurabh
Este comentario me apunta en la dirección correcta. Sin embargo: 1. ¡no necesita comenzar una actividad para tomar una captura de pantalla! simplemente puede inflar un diseño xml en tiempo de ejecución y convertirlo en un mapa de bits como se sugiere aquí ; Dicho esto, puede generar múltiples páginas con diferentes diseños. El desplazamiento no se admite como se dice, pero puede implementar una lista utilizando, por ejemplo, un diseño lineal.
r.pedrosa
11

No es fácil encontrar una solución completa del problema de la conversión de un HTML arbitrario a PDF con letras que no están en inglés en Android. Lo pruebo para las letras Unicode rusas.

Utilizamos tres bibliotecas:

(1) Jsoup (jsoup-1.7.3.jar) para una conversión de HTML a XHTML,

(2) iTextPDF (itextpdf-5.5.0.jar),

(3) XMLWorker (xmlworker-5.5.1.jar).

public boolean createPDF(String rawHTML, String fileName, ContextWrapper context){
    final String APPLICATION_PACKAGE_NAME = context.getBaseContext().getPackageName();
    File path = new File( Environment.getExternalStorageDirectory(), APPLICATION_PACKAGE_NAME );
    if ( !path.exists() ){ path.mkdir(); }
    File file = new File(path, fileName);

    try{

    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
    document.open();

    // Подготавливаем HTML
    String htmlText = Jsoup.clean( rawHTML, Whitelist.relaxed() );
    InputStream inputStream = new ByteArrayInputStream( htmlText.getBytes() );

    // Печатаем документ PDF
    XMLWorkerHelper.getInstance().parseXHtml(writer, document,
        inputStream, null, Charset.defaultCharset(), new MyFont());

    document.close();
    return true;

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return false;
    } catch (DocumentException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    } 

El problema difícil es mostrar letras rusas en PDF utilizando la biblioteca iTextPDF XMLWorker. Para esto debemos crear nuestra propia implementación de la interfaz FontProvider:

public class MyFont implements FontProvider{
    private static final String FONT_PATH = "/system/fonts/DroidSans.ttf";
    private static final String FONT_ALIAS = "my_font";

    public MyFont(){ FontFactory.register(FONT_PATH, FONT_ALIAS); }

    @Override
    public Font getFont(String fontname, String encoding, boolean embedded,
        float size, int style, BaseColor color){

        return FontFactory.getFont(FONT_ALIAS, BaseFont.IDENTITY_H, 
            BaseFont.EMBEDDED, size, style, color);
    }

    @Override
    public boolean isRegistered(String name) { return name.equals( FONT_ALIAS ); }
}

Aquí usamos la fuente estándar de Android Droid Sans, que se encuentra en la carpeta del sistema:

private static final String FONT_PATH = "/system/fonts/DroidSans.ttf";
DenisMath
fuente
1
Gracias por tu parte! Tengo una pregunta: ¿podríamos aplicar alguna regla CSS a HTML?
Phuong
6

Un poco tarde y todavía no lo he probado, pero otra biblioteca que está bajo la licencia BSD es Android PDF Writer .

Actualización He probado la biblioteca yo mismo. Funciona bien con generaciones de PDF simples (proporciona métodos para agregar texto, líneas, rectángulos, mapas de bits, fuentes). El único problema es que el PDF generado se almacena en una Cadena en la memoria, esto puede causar problemas de memoria en documentos de gran tamaño.

Angelo
fuente
¿Alguien puede decirme lo que Android PDF Writer no puede hacer, ese "itext" sí?
M. Usman Khan
1
No mantenido !! Última actualización: 2015-12-14
Mahdi Alkhatib
2

PDFJet ofrece una versión de código abierto de su biblioteca que debería ser capaz de manejar cualquier tarea básica de generación de PDF. Es una solución puramente basada en Java y se afirma que es compatible con Android. Existe una versión comercial con algunas características adicionales que no parece ser demasiado costosa.

IcedDante
fuente
44
no más código abierto
Joshy Francis
0

Tarde, pero relevante para solicitar y con suerte útil. Si utiliza un servicio externo (como se sugiere en la respuesta de CommonsWare), Docmosis tiene un servicio en la nube que podría ayudar: descargar el procesamiento a un servicio en la nube que realiza el procesamiento pesado. Ese enfoque es ideal en algunas circunstancias, pero por supuesto depende de estar conectado a la red.

Paul Jowett
fuente
0

U también puede usar la biblioteca PoDoFo . El objetivo principal es que se publique bajo LGPL. Dado que está escrito en C ++, debe realizar una compilación cruzada con NDK y escribir C-side y Java wrapper. Algunas bibliotecas de terceros se pueden usar desde el proyecto OpenCV . También en OpenCV el proyecto U puede encontrar un android.toolchain.cmakearchivo, que lo ayudará a generar Makefile.

Johnny Doe
fuente