Android實現PDF預覽打印功能

這篇文章主要爲大家詳細介紹了Android實現PDF預覽打印功能,具有一定的參考價值,感興趣的小夥伴們可以參考一下

最近在做一個項目,需要用到android手機連接打印機進行打印的功能,目前在網上找到的教程介紹的都是藍牙連接熱敏打印機(pos機大小的打印機)和藍牙打印機,如果連接日常所見到的網絡打印機,進行打印,很顯然這些教程是做不到的。

由於android沒有提供任何標準,都是自家封的API,參考了WPS的APP的打印功能,決定按照WPS的方案來寫,需要安裝打印服務插件,比如PrinterShare以及三星、HP提供的自家打印服務插件。

一、連接打印管理者

  當程序需要直接管理打印進程時,在收到用戶的打印請求之後,第一步就是連接Android的打印框架,以及操作PrintManager類的實例。這個類允許你實例化一個打印工作並開始打印的生命過程。下面的代碼展示瞭如何獲得一個打印管理者和啓動打印進程。

private void onPrintPdf() {
    PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
    PrintAttributes.Builder builder = new PrintAttributes.Builder();
    builder.setColorMode(PrintAttributes.COLOR_MODE_COLOR);
    printManager.print("test pdf print", new MyPrintAdapter(this,filePath), builder.build());
  }

二、創建打印適配器

  打印適配器會與Android的打印框架相連接,並會處理打印過程的每一個步驟。這個過程要求用戶在創建文檔打印之前選擇打印機及相關的打印選項。這些過程會影響最終的輸出結果,就像用戶選擇了不同打印能力,不同的頁面尺寸,不同的頁面方向一樣。隨着這些選項的設置,打印框架會要求適配器展示並生成一個打印文稿,爲最終的打印做準備。一旦用戶按下了打印按鈕,打印框架會拿到最終的打印文檔然後交付給打印提供者以便打印。

package com.android.guocheng.printdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.pdf.PdfDocument;
import android.graphics.pdf.PdfDocument.PageInfo;
import android.graphics.pdf.PdfRenderer;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.print.pdf.PrintedPdfDocument;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by guocheng on 2017/6/13.
 */
public class MyPrintAdapter extends PrintDocumentAdapter {

  private Context context;
  private int pageHeight;
  private int pageWidth;
  private PdfDocument mPdfDocument;
  private int totalpages = 1;
  private String pdfPath;
  private List<Bitmap> mlist;

  public MyPrintAdapter(Context context,String pdfPath) {
    this.context = context;
    this.pdfPath = pdfPath;
  }

  @Override
  public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal,
             LayoutResultCallback callback,
             Bundle metadata) {

    mPdfDocument = new PrintedPdfDocument(context, newAttributes); //創建可打印PDF文檔對象

    pageHeight = newAttributes.getMediaSize().ISO_A4.getHeightMils() * 72 / 1000; //設置尺寸
    pageWidth = newAttributes.getMediaSize().ISO_A4.getWidthMils() * 72 / 1000;

    if (cancellationSignal.isCanceled()) {
      callback.onLayoutCancelled();
      return;
    }

    ParcelFileDescriptor mFileDescriptor = null;
    PdfRenderer pdfRender = null;
    PdfRenderer.Page page = null;
    try {
      mFileDescriptor = ParcelFileDescriptor.open(new File(pdfPath), ParcelFileDescriptor.MODE_READ_ONLY);
      if (mFileDescriptor != null)
        pdfRender = new PdfRenderer(mFileDescriptor);

      mlist = new ArrayList<>();

      if (pdfRender.getPageCount() > 0) {
        totalpages = pdfRender.getPageCount();
        for (int i = 0; i < pdfRender.getPageCount(); i++) {
          if(null != page)
            page.close();
          page = pdfRender.openPage(i);
          Bitmap bmp = Bitmap.createBitmap(page.getWidth()*2,page.getHeight()*2, Bitmap.Config.ARGB_8888);
          page.render(bmp, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
          mlist.add(bmp);
        }
      }
      if(null != page)
        page.close();
      if(null != mFileDescriptor)
        mFileDescriptor.close();
      if (null != pdfRender)
        pdfRender.close();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

    if (totalpages > 0) {
      PrintDocumentInfo.Builder builder = new PrintDocumentInfo
          .Builder("快速入門.pdf")
          .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
          .setPageCount(totalpages); //構建文檔配置信息

      PrintDocumentInfo info = builder.build();
      callback.onLayoutFinished(info, true);
    } else {
      callback.onLayoutFailed("Page count is zero.");
    }
  }

  @Override
  public void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal,
            final WriteResultCallback callback) {
    for (int i = 0; i < totalpages; i++) {
      if (pageInRange(pageRanges, i)) //保證頁碼正確
      {
        PageInfo newPage = new PageInfo.Builder(pageWidth,
            pageHeight, i).create();
        PdfDocument.Page page =
            mPdfDocument.startPage(newPage); //創建新頁面

        if (cancellationSignal.isCanceled()) { //取消信號
          callback.onWriteCancelled();
          mPdfDocument.close();
          mPdfDocument = null;
          return;
        }
        drawPage(page, i); //將內容繪製到頁面Canvas上
        mPdfDocument.finishPage(page);
      }
    }

    try {
      mPdfDocument.writeTo(new FileOutputStream(
          destination.getFileDescriptor()));
    } catch (IOException e) {
      callback.onWriteFailed(e.toString());
      return;
    } finally {
      mPdfDocument.close();
      mPdfDocument = null;
    }

    callback.onWriteFinished(pageRanges);
  }

  private boolean pageInRange(PageRange[] pageRanges, int page) {
    for (int i = 0; i < pageRanges.length; i++) {
      if ((page >= pageRanges[i].getStart()) &&
          (page <= pageRanges[i].getEnd()))
        return true;
    }
    return false;
  }

  //頁面繪製(渲染)
  private void drawPage(PdfDocument.Page page,int pagenumber) {
    Canvas canvas = page.getCanvas();
    if(mlist != null){
      Paint paint = new Paint();
      Bitmap bitmap = mlist.get(pagenumber);
      int bitmapWidth = bitmap.getWidth();
      int bitmapHeight = bitmap.getHeight();
      // 計算縮放比例
      float scale = (float)pageWidth/(float)bitmapWidth;
      // 取得想要縮放的matrix參數
      Matrix matrix = new Matrix();
      matrix.postScale(scale, scale);
      canvas.drawBitmap(bitmap,matrix,paint);
    }
  }

}


最後看一下效果圖

通過打印服務插件添加打印機就可以進行打印了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持神馬文庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章