当前位置: 首页 > 编程笔记 >

Android实现PDF预览打印功能

萧心水
2023-03-14
本文向大家介绍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);
    }
  }

}


最后看一下效果图

通过打印服务插件添加打印机就可以进行打印了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍vue实现pdf文档在线预览功能,包括了vue实现pdf文档在线预览功能的使用技巧和注意事项,需要的朋友参考一下 针对android系统不支持pdf文档在线预览,可通过引入pdf.js插件实现,其具体实现步骤如下 一、引入插件 方式一:npm install --save pdfjs-dist,安装完成后在vue项目的node_modules出现如下依赖 方式二:只引入pdf.js的

  •   最后,我们要给绘图程序增加打印和打印预览功能。我们希望文档分两页打印,第一页为封面,打印文档名字。第二页输出文档内容,并在页眉上打印文档名字。虽然AppWizard已经自动生成了打印和打印预览的代码,但是许多情况下,并不能符合要求。 这是因为: 1.打印机和窗口(屏幕)显示的分辨率不同:打印机的分辨率用每英寸多少个点来描述,屏幕分辨率用单位面积的像素点来表示。对于同样的Arial字体下的一个字

  • 本文向大家介绍Android实现pdf在线预览或本地预览的方法,包括了Android实现pdf在线预览或本地预览的方法的使用技巧和注意事项,需要的朋友参考一下 最近项目中需要使用在线预览pdf,并要能实现自动播放,我想这样的需求无论如何来说都是很操蛋的 由于本人水平有限,最后讨论将项目需求改成将pdf下载到本地再实现自动播放。 接下来总结下目前能够实现pdf阅读的方案,开发当中需要根据实际需求去选

  • 我知道有很多这样的问题,但从我的研究中,没有什么可以解决在Chrome中抑制PDF查看的问题,以及C# Chromedriver的当前状态。 如果我禁用ChromePDF查看器插件并在命令行中执行--disable-print-preview,我可以让测试手动工作,但我没有设法让任何东西在Selenium中工作。 我试过chromeOptions.AddUserProfilePreference(

  • 在移动端怎么实现pdf打印功能 尝试使用window.print() ios手机浏览器支持window.print,但是在企业微信里面不支持 安卓手机h5不支持window.print 有没有移动端h5实现打印功能的 还是说必须原生app来实现打印。

  • 本文向大家介绍python连接打印机实现打印文档、图片、pdf文件等功能,包括了python连接打印机实现打印文档、图片、pdf文件等功能的使用技巧和注意事项,需要的朋友参考一下 引言 python连接打印机进行打印,可能根据需求的不同,使用不同的函数模块。 如果你只是简单的想打印文档,比如office文档,你可以使用ShellExecute方法,对于微软office的文档、pdf、txt等有用,