【Androidでデータやファイルと戯れる】android.graphics.pdfパッケージを使ってPDFを操作しよう!

このエントリーを Google ブックマーク に追加
[`yahoo` not found]

AndroidでPDFを作成しよう!

API19以降からandroid.graphics.pdfが追加され、Android端末でPDFを作成できるようになりました。
そんなわけで今更ながらPDFの作り方を説明します。
また、今回紹介するandroid.graphics.pdfはCanvasを使ってPDFを作成するのでAndroidのCanvasに向き合うを参考にしてください。

android.graphics.pdfの紹介

まずはパッケージに含まれているクラス群の紹介からいきます。

クラス名 概要
PdfDocument PDFドキュメントの新規作成、ページの管理、ファイルへの書き込み等を行います。
PdfDocument.PageInfo ページ情報を管理するクラス、コンストラクタはプライベートになっているのでPdfDocument.PageInfo.Builderを使用してインスタンスを作成する。
PdfDocument.PageInfo.Builder PdfDocument.PageInfoを作成するためのビルダークラス
PdfDocument.Page PDFの一ページに相当し、ページに書き込むためのCanvasを管理する。
PdfRenderer Bitmapに書き出すためにPDFの全ページを読み込みます。
PdfRenderer.Page Bitmapに書き出すためにPDFの1ページを読み込みます。

PDFを作成するためのクラス群

PdfDocument

シグネチャ 説明
PdfDocument.Page startPage(PdfDocument.PageInfo pageInfo) PageInfoインスタンスを渡して編集可能な Pageを取得する。
closeメソッドを使用した後に使用してはいけません。
void finishPage(PdfDocument.Page page) Pageの編集を終了します。
closeメソッドを使用した後に使用してはいけません。
void writeTo(OutputStream out) PdfDocumentの内容を指定した出力ストリームに書き出します。
closeメソッドを使用した後に使用してはいけません。
また、startPageで編集を開始し、finishPageで編集を終了していないPageがある場合も使用してはいけません。
void close() PdfDocumentに対する操作を終了します。
startPageで編集を開始し、finishPageで編集を終了していないPageがある場合も使用してはいけません。
List getPages() PdfDocumentに含まれるPageInfoのリストを返却します。
PageInfoが存在しない場合は空のリストが返却されます。

PdfDocument.PageInfo

シグネチャ 説明
Rect getContentRect() PDFページの高さと幅をRectクラスのインスタンスで返却する。
縦横のPoint値は1point = 1/72inchとなっています。
int getPageHeight() PDFページの高さのPoint値を返却する。
Point値は1point = 1/72inchとなっています。
int getPageWidth() PDFページの幅のPoint値を返却する。
Point値は1point = 1/72inchとなっています。
int getPageNumber() PDFページのページ番号を返却する。

PdfDocument.PageInfo.Builder

コンストラクタ 説明
PdfDocument.PageInfo.Builder (int pageWidth, int pageHeight, int pageNumber)
  • int pageWidth:PDFページの幅のPoint値を設定する。
    Point値は1point = 1/72inchとなっています。
  • int pageHeight:PDFページの高さのPoint値を設定する。
    Point値は1point = 1/72inchとなっています。
  • int pageNumber:PDFページのページ番号を設定する。

 

シグネチャ 説明
PdfDocument.PageInfo create() 設定した値でPdfDocument.PageInfoを作成する。
PdfDocument.PageInfo.Builder setContentRect(Rect contentRect) PDFページの高さと幅をRectクラスのインスタンスで設定する。
高さと幅のPoint値は1point = 1/72inchとなっています。

PdfDocument.Page

シグネチャ 説明
PdfDocument.PageInfo getInfo() Pageに設定されているPdfDocument.PageInfoを返却する。
Canvas getCanvas() Pageに書き込むためのCanvasを返却する。

PDFを表示するためのクラス群

PdfRenderer

コンストラクタ 説明
PdfRenderer(ParcelFileDescriptor input) ParcelFileDescriptor input:表示するためのFileを指定する。

 

シグネチャ 説明
int getPageCount() PDFのページ数を返却する。
PdfRenderer.Page openPage(int index) PDFの指定したページのPdfRenderer.Pageを返却する。
void close() PdfRendererを閉じます。
boolean shouldScaleForPrinting() 印刷のために拡大縮小を必要とするかを返却します。

PdfRenderer.Page

シグネチャ 説明
int getIndex() ページ番号を返却します。
int getHeight() PDFページの高さのPoint値を返却する。
Point値は1point = 1/72inchとなっています。
int getWidth() PDFページの幅のPoint値を返却する。
Point値は1point = 1/72inchとなっています。
void render(Bitmap destination, Rect destClip, Matrix transform, int renderMode) 渡したBitmapにPDFの内容を描画します。
  • Bitmap destination:PDFの内容を描画するBitmap
  • Rect destClip:Bitmapをクリッピングする領域を指定する。
    クリッピングを行わない場合はnullを指定する。
  • Matrix transform:描画時の変形をMatrixで指定する。
    変形しない場合はnullを指定する。
  • int renderMode:モードを指定する。
    PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY:ディスプレイモード
    PdfRenderer.Page.RENDER_MODE_FOR_PRINT:印刷モード
void close()   PdfRenderer.Pageを閉じます。

まとめ

今回は簡単なPDFの作成とPDFの表示を作成しました。
また、作成処理はとても遅いため、実際は非同期処理で実装した方がよさそうです。

サンプルプログラム

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
public class MainActivity extends AppCompatActivity {
    private String path;
    private PdfDocument pdfDocument;
    private Paint paint;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        path = Environment.getExternalStorageDirectory().getPath() + "/" + Environment.DIRECTORY_DOWNLOADS + "/file.pdf";
        //PDFを作成する。
        createPdf();
        //PDFの内容を画面に表示する。
        showPdf();
    }
 
    public void createPdf(){
        //PDFに書き込む時に使用するPaintを作成する。
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setTextSize(30);
        //PdfDocumentをインスタンス化
        pdfDocument  = new PdfDocument();
        long start = SystemClock.currentThreadTimeMillis();
        FileOutputStream fos = null;
        try {
            //PDFに5ページ追加する。
            for (int i = 0; i < 5 ; i++){
            //ページを追加する。
            addPage(i);
            }
            //PDFの書き込みストリームを生成する。
            fos = new FileOutputStream(path);
            //ストリームにPdfDocumentの内容を書き込む
            pdfDocument.writeTo(fos);
            //PdfDocumentを閉じる
            pdfDocument.close();
        } catch (FileNotFoundException e) {
 
        } catch (IOException e) {
 
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        Toast.makeText(this, "Time:"+(SystemClock.currentThreadTimeMillis() - start) + "ms", Toast.LENGTH_SHORT).show();
    }
 
    public void addPage(int pageNum){
        /**
        * PageInfoインスタンスを作成するためのビルダーをインスタンス化する。
        * 幅:720point(10inch)
        * 高さ:720point(10inch)
        * ページ番号:pageNum
        */
        PdfDocument.PageInfo.Builder builder = new PdfDocument.PageInfo.Builder(720, 720, pageNum);
        //PageInfoをインスタンス化する。
        PdfDocument.PageInfo pageInfo = builder.create();
        //PageInfoから編集可能なPageインスタンスを取得する。
        PdfDocument.Page page = pdfDocument.startPage(pageInfo);
        //Pageにテキストを描画する。
        page.getCanvas().drawText("PdfDocumentで作成した文書の " + pageNum + " ページ目" ,0 ,30, paint);
        //Pageの編集を終了する。
        pdfDocument.finishPage(page);
    }
 
    public void showPdf(){
        //PDF表示用のViewを用意する。
        ScrollView scrollView = new ScrollView(this);
        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        scrollView.addView(linearLayout);
        setContentView(scrollView);
        try {
            //表示するPDFファイルを指定し、ParcelFileDescriptorインスタンスを作成する。
            ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.open(new File(path) , ParcelFileDescriptor.MODE_READ_ONLY);
            //ParcelFileDescriptorインスタンスを使用しPdfRendererをインスタンス化する。
            PdfRenderer pdfRenderer = new PdfRenderer(parcelFileDescriptor);
            //印刷するために拡大縮小が必要かを調べる(今回はトースト表示するだけ)
            Toast.makeText(this, "PdfRenderer#shouldScaleForPrinting():" + pdfRenderer.shouldScaleForPrinting(), Toast.LENGTH_SHORT).show();
            //PDFにページが存在するときだけ表示処理を行う。
            if (pdfRenderer.getPageCount() > 0) {
                for (int i = 0 ; i < pdfRenderer.getPageCount() ; i++){
                    //ページ番号を指定してPdfRenderer.Pageインスタンスを取得する。
                    PdfRenderer.Page page = pdfRenderer.openPage(i);
                    //PdfRenderer.Pageの情報を使って空の描画用Bitmapインスタンスを作成する。
                    Bitmap bitmap = Bitmap.createBitmap(page.getWidth() , page.getHeight() , Bitmap.Config.ARGB_8888);
                    //空のBitmapにPDFの内容を描画する。
                    page.render(bitmap , null,null , PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
                    //PdfRenderer.Pageを閉じる、この処理を忘れると次回読み込む時に例外が発生する。
                    page.close();
                    //画面に表示する
                    ImageView imageView = new ImageView(this);
                    imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT ,ViewGroup.LayoutParams.WRAP_CONTENT ));
                    imageView.setImageBitmap(bitmap);
                    linearLayout.addView(imageView);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Androidゲームプログラミング A to Z

新品価格
¥4,968から
(2017/2/27 22:58時点)


AndroidエンジニアのためのモダンJava

新品価格
¥3,456から
(2017/2/27 23:01時点)


AndroidNDKネイティブプログラミング第2版

中古価格
¥1,893から
(2017/2/28 00:04時点)


Androidアプリ開発逆引きレシピ (PROGRAMMER’S RECiPE)

新品価格
¥3,024から
(2017/2/28 00:06時点)


Android Studio ではじめる Android プログラミング入門 第3版 Android Studio 2対応

新品価格
¥3,240から
(2017/2/28 00:11時点)


アプリを作ろう! Android入門 Android Studio版 Android5対応

新品価格
¥2,160から
(2017/2/28 00:31時点)


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)