Android は PDF ファイルを生成します
1. 公式の方法を使用する
公式の方法は、PdfDocument クラスを使用することです。
1.1 基本的な使い方
/*** * TV コンテンツを PDF ファイルに書き込みます */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) private void newPdf() { // PDF テキスト オブジェクトを作成します PdfDocument document = new PdfDocument(); // 情報を作成します現在のページの場合、ビルダーのパラメータはページの幅と高さ、ページ数を表します PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(binding.pdfTv.getWidth(), binding.pdfTv.getHeight (), 1) .create(); // 現在のページを生成します PdfDocument.Page page = document.startPage(pageInfo); // 現在のページに描画します、つまり、ページのキャンバスに必要なビューを描画します コンテンツの表示 = pdfTv ; content.draw(page.getCanvas()) ; // 現在のページを終了します document.finishPage(page); String filePath = getExternalFilesDir("").getAbsolutePath() + "/test.pdf"; try { FileOutputStream OutputStream = new FileOutputStream(new File(filePath)); //ファイルに書き込みます document.writeTo(outputStream); } catch (IOException e) { e.printStackTrace(); } // document.close(); }
予防
1. ファイルの書き込み許可を申請する必要がある
2. API の最小バージョンは 19 であり、API バージョンには制限があります
1.2 ルート レイアウトのコンテンツから PDF ファイルを生成する
/*** * 画面のコンテンツ (インターフェイス内のテキスト、画像、ボタンなどを含む) を保存します */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) private void pdfTvAndIv() { // PDF テキストを作成しますobject PdfDocument document = new PdfDocument(); //現在のページの情報を作成します。ビルダーのパラメータはページの幅と高さを示し、ページ PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(binding. getRoot().getWidth() , binding.getRoot().getHeight(), 1) .create(); // 現在のページを生成 PdfDocument.Page page = document.startPage(pageInfo); // 現在のページを描画しますページ、つまり、必要なビューを配置します。ビューのビューは、ページのキャンバス上に描画されます。 ; View content = binding.getRoot(); content.draw(page.getCanvas()); // 结束当前页 document.finishPage(page); 文字列ファイルパス = getExternalFilesDir("").getAbsolutePath() + "/tviv.pdf"; { FileOutputStream 出力ストリーム = 新しい FileOutputStream(新しいファイル(ファイルパス)); を試してください。 document.writeTo(outputStream); } catch (IOException e) { e.printStackTrace(); } document.close (); }
それも同じくらい簡単です。binding.getRoot() は XML ファイルのルート レイアウトです
<?xml version="1.0"coding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas .android.com/tools"> <data> </data> < ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".pdf.PdfActivity "> < LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> < TextView android:id="@+id/pdf_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" /> < ImageView android:id="@+id/pdf_iv" android:layout_width ="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@mipmap/logo" android:visibility="visible" /> < Button android:id="@+id/pdf1" android:layout_width="match_parent" android:layout_height="wrap_content"layout_height="wrap_content" android:text="PDF を生成する公式の方法" /> </LinearLayout> </ScrollView> </layout>
1.3 TextView には多くの行があり、複数の画面があります
/*** * PDF ファイルに複数行のテキストを書き込みます */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) private void pdfInterviewContent() { TextView tv_content = binding.pdfTv; // PDF テキスト オブジェクトを作成します PdfDocument document = new PdfDocument(); // pdf の 1 ページの高さ int onePageHeight = tv_content.getLineHeight() * 30; // TextView には何行あるか int lineCount = tv_content.getLineCount(); // ページ数を計算しますTextView は int pdfCount = lineCount % 30 == 0 ? lineCount / 30 : lineCount / 30 + 1; for (int i = 0; i < pdfCount; i++) { .create(); PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfoに分割する必要があります。 .Builder(tv_content.getWidth( ), onePageHeight + 120, 1) .setContentRect(new Rect(0, 60, tv_content.getWidth(), onePageHeight + 60)) PdfDocument.Page ページ = document.startPage(pageInfo); Canvas キャンバス = page.getCanvas(); Canvas.translate(0, -onePageHeight * i); tv_content.draw(キャンバス); document.finishPage(ページ); } //ドキュメント = pdfImageviewContent(ドキュメント); ファイル file = new File(getExternalFilesDir("").getAbsolutePath() + "/test.pdf"); try { FileOutputStream 出力ストリーム = 新しい FileOutputStream(ファイル); document.writeTo(outputStream); } catch (IOException e) { e.printStackTrace(); } document.close(); }
1.4 概要
1. 保存したファイルが少し大きい 2. キャンバスの移動を伴うため、複数画面の内容を保存するのが難しい 3. テキストと絵を同時に保存するのが難しい(1画面を超える場合) 、保存後、画像は空白になります。1 画面までです。保存後は正常に表示されます) 4. インターフェイスに特別なビューがある場合、保存に失敗する可能性があります。たとえば、SurfaceView。 [ソリューションへのリンクが添付されています](https://www.jianshu.com/p/1ebaf5e6fac1)
2.itextの使い方
Itext には主に 2 つのバージョンがあり、1 つは 5.x で、もう 1 つは 7.x です。これら 2 つのバージョンには完全に互換性がありません。違いについては、公式 Web サイトの iText 7 と iText 5: ロードマップ、相違点、を参照してください。|iTextPDF を更新、
5.x のドキュメント: iText Javadoc ホーム
7.x のドキュメント: iText Javadoc ホーム
2.1 7.x
/** * 创建PDF文件 */ private void createPDF(String path) { if (XXPermissions.isGranted(TextActivity.this, Permission.MANAGE_EXTERNAL_STORAGE)) { File file = new File(path); if (file.exists()) { file.delete(); } file.getParentFile().mkdirs(); // 创建Document PdfWriter Writer = null; { writer = new PdfWriter(new FileOutputStream(path));を試してください。 catch (FileNotFoundException e) { Log.e("FileNotFoundException", e.toString()); } PdfDocument pdf_document = 新しい PdfDocument(ライター); // 生成された PDF 文書情報 PdfDocumentInfo info = pdf_document.getDocumentInfo(); // タイトル info.setTitle("First pdf file"); // 著者 info.setAuthor("Quinto"); // 件名 info.setSubject(" test "); // キーワード info.setKeywords("pdf"); // 作成日 info.setCreator("2022-10-20"); ドキュメント document = new Document(pdf_document, PageSize.A4, false); // / テキストのフォント (中国語表示)、サイズ、色 PdfFont font = null; try { font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H"); catch (IOException e) { Log.e("IOException", e.toString()); } float title_size = 36.0f; float text_title_size = 30.0f; float text_size = 24.0f; Color title_color = new DeviceRgb(0, 0) , 0); Color text_title_color = new DeviceRgb(65, 136, 160); Color text_color = new DeviceRgb(43, 43, 43); // 行区切り文字 // 実線: SolidLine() 点線: DottedLine() ダッシュボードline: DashedLine() LineSeparator separator = new LineSeparator(new SolidLine()); separator.setStrokeColor(new DeviceRgb(0, 0, 68)); // 大きなタイトルを追加します テキストのタイトル = new Text("これは PDF ファイルのタイトルです").setFont(font).setFontSize(title_size).setFontColor(title_color); 段落 段落_タイトル = new 段落(タイトル) .setTextAlignment(TextAlignment.CENTER); ドキュメント.add(段落_タイトル); for (int i = 1; i < 10; i++) { // テキストのサブタイトルを追加します テキスト text_title = new Text("th" + i + "line:").setFont(font).setFontSize (text_title_size ).setFontColor(text_title_color); 段落paragraph_text_title = new grammar(text_title); document.add(paragraph_text_title); // テキストコンテンツを追加 String content = "I am text content" + i + i + i + i + i + i + i + i + i + i; Text text = new Text(content).setFont(font).setFontSize(text_size).setFontColor(text_color); 段落paragraph_text = new Paragraph(text); document.add(paragraph_text); // 改行スペースを追加します document.add (new Paragraph("")); // 水平線を追加します document.add(separator); // 分割可能なスペースを追加します document.add(new Paragraph("")); } / ** * リストを追加します * / リスト list = new List().setSymbolIndent(12).setListSymbol("\u2022").setFont(font); list.add(new ListItem("List1")) 。add(new ListItem("リスト 2")) .add(new ListItem("列表3")); document.add(list); / ** * 追加图片 / Text text_image = new Text("图片:").setFont(font).setFontSize(text_title_size).setFontColor(text_title_color); 段落画像 = 新しい段落(text_image); document.add(画像); 画像 image1 = null; 画像 image2 = null; 画像 image3 = null; { /*image1 = new Image(ImageDataFactory.create("/storage/emulated/0/DCIM/Camera/IMG_20221003_181926.jpg")).setWidth(PageSize.A4.getWidth() * 2 / 3); を試してください。 image2 = new Image(ImageDataFactory.create("/storage/emulated/0/Download/互传/folder/证件/XHS_159716343059020494b83-da6a-39d7-ae3b-13fd92cfbb53.jpg")).setWidth(PageSize.A4.getWidth() / 3); image3 = new Image(ImageDataFactory.create("/storage/emulated/0/Download/互传/folder/证件/XHS_1597163520524f0b4df77-8db1-35c6-9dfa-3e0aa74f1fef.jpg")).setWidth(PageSize.A4.getWidth() / 3);*/ image1 = new Image(ImageDataFactory.create("/storage/emulated/0/Pictures/JPEG_20230609_154240_8941441911022988116.jpg")).setWidth(PageSize.A4.getWidth() * 2 / 3); image2 = 新しい Image(ImageDataFactory.create("/storage/emulated/0/Tencent/QQ_Images/-318f738d395e5630.jpg")).setWidth(PageSize.A4.getWidth() / 3); image3 = new Image(ImageDataFactory.create("/storage/emulated/0/Pictures/Screenshots/Screenshot_20230615_145522_com.hermes.wl.jpg")).setWidth(PageSize.A4.getWidth() / 3);} catch ( MalformedURLException e) { Log.e("MalformedURLException", e.toString()); } 段落段落_image = 新しい段落().add(画像1) .add(" ") .add(画像2) .add(" ") .add(画像3); document.add(段落_画像); document.add(new Paragraph("")); / ** * 追加表格 */ テキスト text_table = new Text("Form:").setFont(font).setFontSize(text_title_size).setFontColor(text_title_color); 段落 paragraph_table = new grammar(text_table); document.add(paragraph_table); // 3 列 float[] pointColumnWidths = {100f, 100f, 100f}; テーブル table = new Table(pointColumnWidths); // 境界線のスタイル、色、幅を設定 Color table_color = new DeviceRgb(80, 136, 255); 境界線 border = new DottedBorder(table_color, 3) ); table.setBorder(border); // セルのテキストを中央に設定 table.setTextAlignment(TextAlignment.CENTER); // セルの内容を追加 Color table_header = new DeviceRgb(0, 0, 255); カラーテーブルコンテンツ = 新しい DeviceRgb(255, 0, 0); カラーテーブルフッター = 新しい DeviceRgb(0, 255, 0); テキスト text1 = new Text("姓名").setFont(font).setFontSize(20.0f).setFontColor(table_header); テキスト text2 = new Text("年龄").setFont(font).setFontSize(20.0f).setFontColor(table_header); Text text3 = new Text("性别").setFont(font).setFontSize(20.0f).setFontColor(table_header); table.addHeaderCell(新しい段落(テキスト1)); table.addHeaderCell(新しい段落(テキスト2)); table.addHeaderCell(新しい段落(text3)); テキスト text4 = new Text("张三").setFont(font).setFontSize(15.0f).setFontColor(table_content); テキスト text5 = new Text("30").setFont(font).setFontSize(15.0f).setFontColor(table_content); テキスト text6 = new Text("男").setFont(font).setFontSize(15.0f).setFontColor(table_content); table.addCell(新しい段落(text4)); table.addCell(新しい段落(text5)); table.addCell(新しい段落(text6)); テキスト text7 = new Text("丽萨").setFont(font).setFontSize(15.0f).setFontColor(table_footer); テキスト text8 = new Text("20").setFont(font).setFontSize(15.0f).setFontColor(table_footer); Text text9 = new Text("女").setFont(font).setFontSize(15.0f).setFontColor(table_footer); table.addFooterCell(新しい段落(text7)); テーブル。 table.addFooterCell(new Paragraph(text9)); // PDF ファイルに表を追加 document.add(table); / ** * ヘッダー、フッター、ウォーターマークを追加 */ Rectangle pageSize; PdfCanvas Canvas; int n = pdf_document .getNumberOfPages(); Log.i("zxd", "createPDF: " + n); for (int i = 1; i <= n; i++) { PdfPage page = pdf_document.getPage(i); Log.i ( "zxd", "createPDF page: " + page.getPageSize()); pageSize = page.getPageSize(); Canvas = new PdfCanvas(page); // ヘッダー Canvas.beginText().setFontAndSize(font, 7) .moveText(pageSize.getWidth() / 2 - 18, pageSize.getHeight() - 10) .showText("私がヘッダーです") .endText(); // フッター Canvas.setStrokeColor(text_color) .setLineWidth( . 2f) .moveTo(pageSize.getWidth() / 2 - 30, 20) .lineTo(pageSize.getWidth() / 2 + 30, 20).ストローク(); Canvas.beginText().setFontAndSize(font, 7) 。 moveText(pageSize.getWidth() / 2 - 6, 10) .showText(String.valueOf(i)) .endText(); // ウォーターマーク 段落 p = 新しい Paragraph("Quinto").setFontSize(60); Canvas.saveState(); PdfExtGState gs1 = new PdfExtGState().setFillOpacity(0.2f); Canvas.setExtGState(gs1); document.showTextAligned(p, pageSize) .getWidth() / 2、pageSize.getHeight() / 2、 pdf_document.getPageNumber(page)、 TextAlignment.CENTER、VerticalAlignment.MIDDLE、45); Canvas.restoreState(); } // document.close(); を閉じます。 Toast.makeText(this, "PDF ファイルが生成されました", Toast.LENGTH_SHORT).show(); } else { //許可がありません //requestPermission(); } }
予防
1.pdfdocument.getPageSize() はオブジェクト iText7 のインスタンスとして設定されておらず、即時更新のパラメーターが true に設定されているため、ページ サイズを取得するとエラーが報告されます。
コンストラクターに3 番目のパラメーター ( )を渡す文档
ことで、デフォルトでその内容を更新しないように指示できます。false
immediateflush
ドキュメント document = new Document(pdf_document, PageSize.A4, false);
pdfdocument.getPageSize() がオブジェクト iText7 のインスタンスに設定されていません
2. 画像リソースが見つからない場合、IO エラーが報告されます。
2.2 7.x の基本的な使用法
2.2.1 中国語を表示する
itext7 がデフォルトのフォントを使用して中国語を表示する場合、デフォルトのフォントは中国語をサポートしていないため、生成された PDF 内の中国語は空白で表示されます。この問題を解決するには、フォントを自分でインポートする必要があります。
1. 中国語フォント (.ttf ファイル、SourceHanSansCN.ttf) をダウンロードします。
2. ローカルフォントスタイルをロードする
InputStream inputStream = new FileInputStream(new File("SourceHanSansCN.ttf")); //3 番目のパラメータは組み込みフォントかどうかに関係なく埋め込まれます。ここでは自分で用意したものなので false を渡します PdfFont font = PdfFontFactory.createFont( IOUtils.toByteArray(inputStream)、PdfEncodings.IDENTITY_H、false);
3.フォントを設定する
//デフォルトはA4用紙サイズです Document document = new Document(pdfDocument, new PageSize()); document.setFont(font);
2.2.2 解像度
PDF 印刷が必要な場合は、解像度の問題が発生します。
itext では、挿入された画像以外はベクターグラフィックスなので、解像度を気にする必要はありません。挿入された画像の解像度だけを確保する必要があります。itext で生成される画像のデフォルトの解像度は 72dpi ですここで、次のようないくつかの処理が必要です。
int デフォルト Dpi = 72; int targetDpi = 300; 画像テスト = new Image(ImageDataFactory.create("test.jpg")); test.scale(デフォルトDpi/ターゲットDpi, デフォルトDpi/ターゲットDpi);
2.2.3 レイアウト
Itextの座標系は下図のようになります 絶対レイアウトの場合は要素の左辺と下辺から長さを計算する必要があります 相対レイアウトの場合は上から順に要素を配置します下。
絶対レイアウト
setFixedPosition(フロート左、フロート下、フロート幅)
相対レイアウト
相対レイアウトの場合はsetFixedPositionは不要で、上下左右の距離の長さのみ設定可能です。
setMarginLeft(浮動小数点値); setMarginRight(浮動小数点値); setMarginBottom(浮動小数点値); setMarginTop(浮動小数点値); setMargin(float commonMargin);
2.2.4 自動ページネーション + ページ番号の生成
絶対レイアウトを使用する場合、ほとんどの場合、ページ コンテンツのサイズと位置は固定されており、ページングもコードを自分で記述して制御する必要があります。ただし、PDF の内容が固定されていない場合、現時点では絶対レイアウトを使用するのはあまり柔軟性がなく、要素の高さを計算して絶対位置を設定する必要があります。相対レイアウトを使用することを選択する方が簡単です。コードは次のとおりです: class PageEventHandlerimplements IEventHandler { private Document document; private PdfFont font; // 統一フォントと中国語フォントが必要なため、pdffont パラメータが追加されます。そのような要件がない場合、 public PageEventHandler(Document document、PdfFont フォントは追加できない場合があります ){ this.document = document; this.font = font; } @Override public void handleEvent(Event イベント) { PdfDocumentEvent pdfEvent = (PdfDocumentEvent) イベント; PdfPage page = pdfEvent.getPage() ; PdfDocument pdfDoc = pdfEvent.getDocument(); // 現在のページ番号を取得します int pageNumber = pdfDoc.getPageNumber(page); PdfCanvas pdfCanvas = new PdfCanvas( page.newContentStreamBefore(), page.getResources(), pdfDoc); / / In 前の要素から 50 の距離にページ番号を書き込みます this.document.setTopMargin(50f); pdfCanvas.beginText () .setFontAndSize(this.font, 32) //現在のページを、フォントの配置により、ページは一般に幅が広くなります。原点も左下隅にあるため、ここでは X 軸からページ番号の幅の半分が減算され、ページ番号が中央に書かれていることを確認します。 // y -axisは下から20pxです .moveText(PageSize.A4.getWidth()/2-32/ 2, 20f) .showText(String.valueOf(pageNumber)) .endText(); pdfCanvas.release(); } } //pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new PageEventHandler(document, font)) を 使用。
2.2.5 共通コンポーネント
テーブル
//テーブルの各列の幅を指定せず、列の内容に合わせます public Table(int numColumns); //各列の幅を指定します public Table(float[] pointColumnWidths); //セルを追加しますテーブル、デフォルトは水平方向に追加で、指定された列数に達すると、行は自動的に折り返されます public Table addCell(Cell cell); //テーブルまたはセルの境界線を設定します。ここで注意が必要です。枠線を表示したくない場合は、各セルで枠線をなしに設定する必要がありますが、表の枠線を設定した場合のみ枠線が表示されます public T setBorder(Border border); //枠線なし cell.setBorder (Border.NO_BORDER); //実線の境界線 cell.setBorder(new SolidBorder(1)); //点線の境界線 cell.setBorder(new DashedBorder(1)); //4 つは丸い角です cell.setBorderRadius(new BorderRadius(10f) )); // 丸い角 - 右下隅 cell.setBorderBottomRightRadius(new BorderRadius(10f)); // 丸い角 - 左下角 cell.setBorderBottomLeftRadius(new BorderRadius(10f)); //角の丸い - 右上隅 cell.setBorderTopRightRadius(new BorderRadius(10f)); //角の丸い - 左上隅 cell.setBorderTopLeftRadius(new BorderRadius(10f)); / /About 表の角丸、つまり角丸は設定されているようで有効にならないのですが、外側の表の枠線をなしにして、内側のセルの枠線を設定することで実現できます
テーブル付きのプログレスバーを実装する
-
アイデア: 外側の層は 1 行 1 列のテーブルで、内側のセルには実際の進行状況として 1 行 1 列のテーブルが設定され、内側のテーブルの幅はパーセンテージに従って計算されます。
//ここでのパーセントは 10 進数です public void processBar(Document document, float width, float パーセント){ float processWidth = width * パーセント; DeviceRgb processColor = new DeviceRgb(11,11,11);//色を書き込むだけ DeviceRgb processBgColor = new DeviceRgb(101,11,11);//カラーを書き込むだけ Table table = new Table(new float[]{width}).setMargin(0).setPadding(0);//不要なギャップを追加すると、クレードル テーブル processTable = new Table(new float[]{processWidth}).setMargin(0).setPadding(0); processTable.addCell(new Cell().setBorder(Border.NO_BORDER) .setMargin(0 ).setPadding(0) ).setBackgroundColor(processColor)); table.addCell(new Cell().setBorder(Border.NO_BORDER).setBackgroundColor(processBgColor) .setMargin(0).setPadding(0).setBorder(Border.NO_BORDER).add(processTable)); }
段落
段落は最も頻繁に使用されるクラスであり、このクラスは PDF にテキストを書き込むために使用されます。
段落 para = new grammar("私は段落です") .setFontSize(14)//フォント サイズを設定します。setBold ()//テキストを太字に設定します。setFontColor (new DeviceRgb(0,0,0))// Set Font color.setTextAlignment(TextAlignment.CENTER)//テキストは水平方向に中央揃えになります 。setFixedLeading(14);//CSS の行の高さと同様
場合によっては、同じ段落内のテキストの一部を別の色またはスタイルに設定する必要があるという要件が発生することがありますが、このときは、次のように Text を使用して処理できます。
//この処理方法では太字の問題には対応できません。太字にしたい文字が段落の途中にある場合、それを太字にすると全体が太字になってしまいます(イタリック体は同じです) para . add(new Text("違うものになりたい").setFontSize("20").setFontColor(new DeviceRgb(255,255,255)));
画像
//画像解像度の問題については、上記の解像度セクションを参照してください 。 Image image = new Image(ImageDataFactory.create("/home/test.jpg"));
参考: Itext7 は PDF の最も完全な API 概要を生成します
2.2.6 基本的な使い方
private void pdf1() { path = getExternalFilesDir("").getAbsolutePath() + "/itext_basic.pdf"; PdfWriter Writer;// 書き込み送信の出力ストリームの PdfWriter を作成します。 try { writer = new PdfWriter(new FileOutputStream(path)); PdfFont フォント = PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN); PdfDocument pdf = 新しい PdfDocument(ライター); ドキュメント document = 新しいドキュメント(pdf); Text text = new Text("iText を使用して作成された Hello World PDF") .setFont(font) .setFontSize(15) .setFontColor(ColorConstants.MAGENTA); //ドキュメントに段落を追加します document.add(new Paragraph(text)); document.close(); } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } }
2.2.7 フォントスタイル
{ PdfDocument pdf = new PdfDocument(new PdfWriter(path)); を試してください。 PdfFont フォント = PdfFontFactory.createFont(StandardFonts.COURIER); スタイル style = new Style().setFont(font) .setFontSize(14) .setFontColor(ColorConstants.RED) .setBackgroundColor(ColorConstants.YELLOW); ドキュメント document = new Document(pdf); document.add(new Paragraph() .add("この PDF では、 ") .add(new Text("テキストはスタイル設定されています").addStyle(style)) .add(" iText を使用しています ") .add(new Text( "スタイル").addStyle(スタイル)) .add(".")); document.close() ; } catch (IOException e) { e.printStackTrace(); }
2.2.8 テキストから PDF へ
private void pdf3(String source, String des) { try { BufferedReader br = new BufferedReader(new FileReader(source)); PdfDocument pdf = new PdfDocument(new PdfWriter(des)); ドキュメント document = 新しいドキュメント(pdf); 文字列行; PdfFont フォント = PdfFontFactory.createFont(StandardFonts.COURIER); while ((line = br.readLine()) != null) { document.add(new Paragraph(line).setFont(font)); br.close (); document.close(); } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } }
参考: iText 7 を使用して Java で中国語 PDF を生成する
2.3 PDFを開く
/** * 打开PDF文件 */ private void openPDF() { new Handler().postDelayed(new Runnable() { @Override public void run() { try { FileUtils.openFile(context, new File(path)); catch (例外 e) { Log.e("例外", e.toString()); } } }, 1000); }
PDFファイルを開く
/** * 打开PDF文件 * * @param context * @param url * @throws ActivityNotFoundException * @throws IOException */ public static void openFile(Context context, File url) throws ActivityNotFoundException { if (url.exists()) { Uri uri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".fileprovider", url); String urlString = url.toString().toLowerCase(); Intent 意図 = new Intent(Intent.ACTION_VIEW) ); テント.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); /** * セキュリティ */ List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfosolveInfo : resInfoList) { String packageName =solveInfo.activityInfo.packageName; context.grantU riPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMIS)シオン| Intent.FLAG_GRANT_READ_URI_PERMISSION); } // URL と拡張子を比較して、開きたいファイルの種類を確認します。 // if 条件が一致すると、プラグインは正しいインテント (mime) タイプを設定します。 // Android は、ファイルを開くためにどのプログラムを使用するかを認識します if (urlString.toLowerCase().contains(".doc") || urlString. toLowerCase().contains(".docx")) { // Word 文書 テント.setDataAndType(uri, "アプリケーション/msword"); } else if (urlString.toLowerCase().contains(".pdf")) { // PDF ファイル tent.setDataAndType(uri, "application/pdf"); } else if (urlString.toLowerCase().contains(".ppt") || urlString.toLowerCase().contains(".pptx")) { // Powerpoint ファイル tent.setDataAndType(uri, "application/vnd.ms -パワーポイント"); } else if (urlString.toLowerCase().contains(".xls") || urlString.toLowerCase().contains(".xlsx")) { // Excel ファイル tent.setDataAndType(uri, "application/vnd. } else if (urlString.toLowerCase().contains(".zip") || urlString.toLowerCase().contains(".rar")) { // ZIP ファイル tent.setDataAndType(uri, "application/trap") ; } else if (urlString.toLowerCase().contains(".rtf")) { // RTF ファイル tent.setDataAndType(uri, "application/rtf"); } else if (urlString.toLowerCase().contains(".wav") || urlString.toLowerCase().contains(".mp3")) { // WAV/MP3 オーディオ ファイル tent.setDataAndType(uri, "audio/ *"); else if (urlString.toLowerCase().contains(". テント.setDataAndType(uri, "画像/gif"); } else if (urlString.toLowerCase().contains(".jpg") || urlString.toLowerCase().contains(".jpeg") || urlString.toLowerCase().contains(".png")) { / / JPG ファイル tent.setDataAndType(uri, "image/jpeg"); } else if (urlString.toLowerCase().contains(".txt")) { // テキスト ファイル tent.setDataAndType(uri, "text/plain"); } else if (urlString.toLowerCase().contains(".3gp") || urlString.toLowerCase().contains(".mpg") || urlString.toLowerCase().contains(". || urlString.toLowerCase().contains(".mpe") || urlString.toLowerCase().contains(".mp4") || urlString.toLowerCase().contains(".avi")) { // ビデオfilestent.setDataAndType (uri, "video/*"); } else { // 必要に応じて、他のファイルのインテント タイプを定義することもできます // また、他の不明な拡張子を管理するには、以下の else 句を使用します //この場合 、Android はデバイスにインストールされているすべてのアプリを表示します// そのため 、 どのアプリを使用するかを選択できます 。; } それ以外の場合は { Toast.makeText(context, "ファイルが存在しません", Toast.LENGTH_SHORT).show(); } }
マニフェスト.xml
<プロバイダー android:name="androidx.core.content.FileProvider" android:authorities="com.zg.pdfdemo.fileprovider" android:exported="false" android:grantUriPermissions="true"> <メタデータ android:name ="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider>
プロバイダーパス
<?xml version="1.0"coding="utf-8"?> <パス> <external-path name="external_files" path="."/> </paths>
2.4 pdfRender の簡単な使い方
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void pdf4() { path = getExternalFilesDir("").getAbsolutePath() + "/itext_basic.pdf"; try { // 1. ファイルを作成します File pdfFile = new File ( path); // 2. ParcelFileDescriptor オブジェクトを取得します ParcelFileDescriptor ParcelFileDescriptor = ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY); // 3. PdfRenderer オブジェクトを作成します PdfRenderer renderer = new PdfRenderer(parcelFileDescriptor); // ページ データをレンダリングしますbitmap // 1. ページ番号データの取得 Page オブジェクト PdfRenderer.Page page = renderer.openPage(0); int pageCount = renderer.getPageCount(); Log.i("zxd", "pdf4: Total = " + pageCount); // 2. ARGB_8888 ビットマップの作成 Bitmap bitmap = Bitmap.createBitmap(page.getWidth(), page.getHeight(), Bitmap.Config. ARGB_8888 ); //3. レンダリング page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); //iv にレンダリング binding.iv.setImageBitmap(bitmap); //現在のページ データを閉じる page.close( ); } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } }
要約する
利点: Android 自体によって提供されるため、比較的軽量であり、サードパーティの SDK に依存する必要がなく、コア コードはすべてネイティブに実装されており、実行効率が比較的高いです。
デメリット:Android 5.0以降でしか利用できず、ネイティブ実装のため描画アルゴリズムを自分でカスタマイズすることができず、利用時にスレッドセーフを自分で制御するのが面倒。
参考:
【APIリファレンスドキュメント】(https://www.apiref.com/)