Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate and print a PDF with specific size in Android

I'm working in an Android application, and I want to generate and print a PDF. But I'm having some trouble. I need to generate the PDF with 80mm of width, and the height may vary.

I'm trying this:

public class PDFGenerator implements Runnable {
    private Context ctx;
    private View view;
    private Intent mShareIntent;
    private OutputStream os;

    public PDFGenerator(Context ctx, View view) {
        this.ctx = ctx;
        this.view = view;
        makeAndSharePDF();
    }

    public void makeAndSharePDF() {
        new Thread(this).start();
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void run() {
        PrintAttributes printAttrs = new PrintAttributes.Builder().
                setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME).
                setMediaSize(PrintAttributes.MediaSize.ISO_C7).
                setResolution(new PrintAttributes.Resolution("zooey", ctx.PRINT_SERVICE, 500, 500)).
                setMinMargins(PrintAttributes.Margins.NO_MARGINS).
                build();

        PdfDocument document = new PrintedPdfDocument(ctx, printAttrs);
        PdfDocument.PageInfo pageInfo = new  PdfDocument.PageInfo.Builder(view.getWidth(), view.getHeight(), 1).create();
        PdfDocument.Page page = document.startPage(pageInfo);
        view.draw(page.getCanvas());
        document.finishPage(page);

        try {
            File pdfDirPath = new File(ctx.getFilesDir(), "pdfs");
            pdfDirPath.mkdirs();
            File file = new File(pdfDirPath, "danfe.pdf");
            Uri contentUri = FileProvider.getUriForFile(ctx, "br.com.rdscodes.nfcelular", file);
            os = new FileOutputStream(file);
            document.writeTo(os);
            document.close();
            os.close();
            shareDocument(contentUri);
        } catch (IOException e) {
            throw new RuntimeException("Error generating file", e);
        }
    }

    private void shareDocument(Uri uri) {
        mShareIntent = new Intent();
        mShareIntent.setAction(Intent.ACTION_SEND);
        mShareIntent.setType("application/pdf");
        mShareIntent.putExtra(Intent.EXTRA_SUBJECT, "NFC-e");
        mShareIntent.putExtra(Intent.EXTRA_STREAM, uri);
        ctx.startActivity(mShareIntent);
    }
}

This code generates the PDF, but with letter size.

I saw in Android Developers media size documentation that the "ISO_C7" media size is the size the i almost want, but i can change all the "printAttrs" and nothing changes on the final result of the PDF.

Are there better ways to generate and print a PDF? How can I generate my PDF with 80mm of width?

This part of the app was made by an old employee.

Thanks.

like image 210
Henrique Navarro Marçulo Avatar asked Aug 07 '15 18:08

Henrique Navarro Marçulo


People also ask

How do I Print a PDF A3 size?

In order to set the Paper Size to A3, go to the File menu – Print – Page Setup and from “Page” tab, “Paper Size” field, select A3 and press “OK” in order for changes to take effect. After that, go to the File menu – Export and select the “Export to PDF” option.


2 Answers

Just so you don't break your head over it, like I did, check out this bug report: https://code.google.com/p/android/issues/detail?id=180405

Considering this bug report, I'd say it's a problem with the android printing interface and you can't really set any defaults using PrintAttributes, well at least not until android N.

If you find/found a workaround, please let me know :)

like image 154
Radovan Obal Avatar answered Sep 25 '22 01:09

Radovan Obal


I know it's a bit later. However, I have made my custom size with this approach : ( widthMils: 5800, heightMils: 40000). The unit of measurement is: one thousandth of an inch.

private PrintAttributes getDefaultPrintAttrs() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return null;

    PrintAttributes.MediaSize customSize = new 
    PrintAttributes.MediaSize("COIL", "COIL", 5800,40000);
    customSize.asPortrait();

    return new PrintAttributes.Builder()
            .setMediaSize(customSize)
            .setResolution(new PrintAttributes.Resolution("RESOLUTION_ID", "RESOLUTION_ID", 600, 600))
            .setMinMargins(PrintAttributes.Margins.NO_MARGINS)
            .build();

}
like image 39
Cassio Seffrin Avatar answered Sep 23 '22 01:09

Cassio Seffrin