一:添加依赖

implementation 'com.itextpdf:itext7-core:7.1.13'

二:清单文件AndroidManifest.xml

添加权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

在<application>中添加

android:requestLegacyExternalStorage="true"

添加provider

<providerandroid:name="androidx.core.content.FileProvider"android:authorities="com.example.demo.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/provider_paths" />
</provider>

在res目录下新建xml目录,并创建provider_paths.xml文件

<?xml version="1.0" encoding="utf-8"?>
<paths><external-path name="external_files" path="."/>
</paths>

三:文件工具类FileUtils

package com.example.demo;import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.widget.Toast;import androidx.core.content.FileProvider;import java.io.File;
import java.io.IOException;
import java.util.List;public class FileUtils {/*** 获取包含文件的应用程序路径** @return String 根目录路径*/public static String getAppPath() {File dir = new File(android.os.Environment.getExternalStorageDirectory()+ File.separator+ "PDF"+ File.separator);if (!dir.exists()) {dir.mkdirs();}return dir.getPath() + File.separator;}/*** 打开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 intent = new Intent(Intent.ACTION_VIEW);intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);/*** Security*/List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);for (ResolveInfo resolveInfo : resInfoList) {String packageName = resolveInfo.activityInfo.packageName;context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);}// 通过比较url和扩展名,检查您要打开的文件类型。// 当if条件匹配时,插件设置正确的意图(mime)类型// 所以Android知道用什么程序打开文件if (urlString.toLowerCase().contains(".doc")|| urlString.toLowerCase().contains(".docx")) {// Word documentintent.setDataAndType(uri, "application/msword");} else if (urlString.toLowerCase().contains(".pdf")) {// PDF fileintent.setDataAndType(uri, "application/pdf");} else if (urlString.toLowerCase().contains(".ppt")|| urlString.toLowerCase().contains(".pptx")) {// Powerpoint fileintent.setDataAndType(uri, "application/vnd.ms-powerpoint");} else if (urlString.toLowerCase().contains(".xls")|| urlString.toLowerCase().contains(".xlsx")) {// Excel fileintent.setDataAndType(uri, "application/vnd.ms-excel");} else if (urlString.toLowerCase().contains(".zip")|| urlString.toLowerCase().contains(".rar")) {// ZIP fileintent.setDataAndType(uri, "application/trap");} else if (urlString.toLowerCase().contains(".rtf")) {// RTF fileintent.setDataAndType(uri, "application/rtf");} else if (urlString.toLowerCase().contains(".wav")|| urlString.toLowerCase().contains(".mp3")) {// WAV/MP3 audio fileintent.setDataAndType(uri, "audio/*");} else if (urlString.toLowerCase().contains(".gif")) {// GIF fileintent.setDataAndType(uri, "image/gif");} else if (urlString.toLowerCase().contains(".jpg")|| urlString.toLowerCase().contains(".jpeg")|| urlString.toLowerCase().contains(".png")) {// JPG fileintent.setDataAndType(uri, "image/jpeg");} else if (urlString.toLowerCase().contains(".txt")) {// Text fileintent.setDataAndType(uri, "text/plain");} else if (urlString.toLowerCase().contains(".3gp")|| urlString.toLowerCase().contains(".mpg")|| urlString.toLowerCase().contains(".mpeg")|| urlString.toLowerCase().contains(".mpe")|| urlString.toLowerCase().contains(".mp4")|| urlString.toLowerCase().contains(".avi")) {// Video filesintent.setDataAndType(uri, "video/*");} else {// 如果你愿意,你也可以为任何其他文件定义意图类型// 另外,使用下面的else子句来管理其他未知扩展// 在这种情况下,Android将显示设备上安装的所有应用程序// 因此您可以选择使用哪个应用程序intent.setDataAndType(uri, "*/*");}intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);} else {Toast.makeText(context, "文件不存在", Toast.LENGTH_SHORT).show();}}
}

四:权限工具类Permissions

package com.example.demo;import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;public class Permissions {/*** 弹出权限提示框*/public static void showPermissionsSettingDialog(Context context, String permission) {String msg = "";if (permission.equals("android.permission.READ_EXTERNAL_STORAGE") ||permission.equals("android.permission.WRITE_EXTERNAL_STORAGE")) {msg= "本App需要“允许储存空间”权限才能正常运行,请点击确定,进入设置界面进行授权处理";}AlertDialog.Builder builder = new AlertDialog.Builder(context);builder.setMessage(msg);builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {showSettings(context);}});builder.setCancelable(false);builder.show();}/*** 如果授权失败,就要进入App权限设置界面*/public static void showSettings(Context context) {Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);Uri uri = Uri.fromParts("package", context.getPackageName(), null);intent.setData(uri);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);}
}

五:布局文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"tools:context=".MainActivity"><Buttonandroid:id="@+id/create_pdf"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="生成PDF文件"android:layout_marginTop="100dp"android:layout_marginBottom="30dp"/><Buttonandroid:id="@+id/open_pdf"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="打开PDF文件"/></LinearLayout>

六:使用iText7生成PDF文件,并打开PDF文件

package com.example.demo;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfDocumentInfo;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.draw.SolidLine;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.LineSeparator;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.property.TextAlignment;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class MainActivity extends AppCompatActivity {private Button create_pdf;private Button open_pdf;private String path;private Context context;private boolean isPermissions = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);requestPermission();initView();}private void initView() {create_pdf = findViewById(R.id.create_pdf);open_pdf = findViewById(R.id.open_pdf);context = getApplicationContext();path = FileUtils.getAppPath() + "test.pdf";Log.e("pdf保存路径", path);create_pdf.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {createPDF(path);}});open_pdf.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {openPDF();}});}/*** 创建PDF文件*/private void createPDF(String path) {if (isPermissions) {File file = new File(path);if (file.exists()) {file.delete();}file.getParentFile().mkdirs();// 创建DocumentPdfWriter writer = null;try {writer = new PdfWriter(new FileOutputStream(path));} catch (FileNotFoundException e) {Log.e("FileNotFoundException", e.toString());}PdfDocument pdf_document = new PdfDocument(writer);// 生成的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 document = new Document(pdf_document, PageSize.A4, true);// 文字字体(显示中文)、大小、颜色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()  仪表盘线:DashedLine()LineSeparator separator = new LineSeparator(new SolidLine());separator.setStrokeColor(new DeviceRgb(0, 0, 68));// 添加大标题Text title = new Text("这里是pdf文件标题").setFont(font).setFontSize(title_size).setFontColor(title_color);Paragraph paragraph_title = new Paragraph(title).setTextAlignment(TextAlignment.CENTER);document.add(paragraph_title);for (int i = 1; i < 10; i++) {// 添加文本小标题Text text_title = new Text("第" + i + "行:").setFont(font).setFontSize(text_title_size).setFontColor(text_title_color);Paragraph paragraph_text_title = new Paragraph(text_title);document.add(paragraph_text_title);// 添加文本内容String 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 paragraph_text = new Paragraph(text);document.add(paragraph_text);// 添加可换行空间document.add(new Paragraph(""));// 添加水平线document.add(separator);// 添加可换行空间document.add(new Paragraph(""));}/*** 添加列表*/List list = new List().setSymbolIndent(12).setListSymbol("\u2022").setFont(font);list.add(new ListItem("列表1")).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);Paragraph image = new Paragraph(text_image);document.add(image);Image image1 = null;Image image2 = null;Image image3 = null;try {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);} catch (MalformedURLException e) {Log.e("MalformedURLException", e.toString());}Paragraph paragraph_image = new Paragraph().add(image1).add("  ").add(image2).add("  ").add(image3);document.add(paragraph_image);document.add(new Paragraph(""));/*** 添加表格*/Text text_table = new Text("表单:").setFont(font).setFontSize(text_title_size).setFontColor(text_title_color);Paragraph paragraph_table = new Paragraph(text_table);document.add(paragraph_table);// 3列float[] pointColumnWidths = {100f, 100f, 100f};Table table = new Table(pointColumnWidths);// 设置边框样式、颜色、宽度Color table_color = new DeviceRgb(80, 136, 255);Border border = new DottedBorder(table_color, 3);table.setBorder(border);// 设置单元格文本居中table.setTextAlignment(TextAlignment.CENTER);// 添加单元格内容Color table_header = new DeviceRgb(0, 0, 255);Color table_content = new DeviceRgb(255, 0, 0);Color table_footer = new DeviceRgb(0, 255, 0);Text text1 = new Text("姓名").setFont(font).setFontSize(20.0f).setFontColor(table_header);Text 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(new Paragraph(text1));table.addHeaderCell(new Paragraph(text2));table.addHeaderCell(new Paragraph(text3));Text text4 = new Text("张三").setFont(font).setFontSize(15.0f).setFontColor(table_content);Text text5 = new Text("30").setFont(font).setFontSize(15.0f).setFontColor(table_content);Text text6 = new Text("男").setFont(font).setFontSize(15.0f).setFontColor(table_content);table.addCell(new Paragraph(text4));table.addCell(new Paragraph(text5));table.addCell(new Paragraph(text6));Text text7 = new Text("丽萨").setFont(font).setFontSize(15.0f).setFontColor(table_footer);Text 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(new Paragraph(text7));table.addFooterCell(new Paragraph(text8));table.addFooterCell(new Paragraph(text9));// 将表格添加进pdf文件document.add(table);/*** 添加页眉、页脚、水印*/Rectangle pageSize;PdfCanvas canvas;int n = pdf_document.getNumberOfPages();for (int i = 1; i <= n; i++) {PdfPage page = pdf_document.getPage(i);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).stroke();canvas.beginText().setFontAndSize(font, 7).moveText(pageSize.getWidth() / 2 - 6, 10).showText(String.valueOf(i)).endText();// 水印Paragraph p = new 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();}}/*** 打开PDF文件*/private void openPDF() {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {try {FileUtils.openFile(context, new File(path));} catch (Exception e) {Log.e("Exception", e.toString());}}}, 1000);}/*** 动态申请权限*/private void requestPermission() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {// 先判断有没有权限if (Environment.isExternalStorageManager()) {isPermissions = true;} else {AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setMessage("生成PDF文件需要“允许所有文件访问”权限才能正常运行,请点击确定,进入设置界面进行授权处理");builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {startActivityForResult(new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION), 1024);}});builder.setCancelable(false);builder.show();}} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 先判断有没有权限if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {isPermissions = true;} else {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1024);}} else {isPermissions = true;}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == 1024) {if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {isPermissions = true;} else {//拒绝就要强行跳转设置界面Permissions.showPermissionsSettingDialog(this, permissions[0]);}}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {super.onActivityResult(requestCode, resultCode, intent);if (requestCode == 1024 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {if (Environment.isExternalStorageManager()) {isPermissions = true;} else {Toast.makeText(context, "存储权限获取失败", Toast.LENGTH_SHORT).show();}}}
}

七:生成的PDF文件预览图

Android使用iText7生成PDF文件相关推荐

  1. Android 使用PdfDocument生成PDF文件及遇到的问题

    一.PdfDocument使用 PdfDocument是Android原生的生成pdf文件的类,这个类的使用可参考: https://developer.android.google.cn/refer ...

  2. Android环境下生成PDF文件

    一.背景 公司需要一个从本地选择图片生成pdf文件并上传的功能,由于Android本身并没有对pdf的支持,这里选择使用一个第三方的库来达成需求. 二.库的选择 2.1 当前主流的库 在众多Java语 ...

  3. android 原生 bitmap 生成pdf文件

    写这篇文章,是因为我编写这块功能时,公司要求能用android原生代码就不要用第三方,所以,我找了好久都没找到谁在用原生代码生成pdf文件,尤其是把bitmap写入pdf中,所以,在这里,我把原生 生 ...

  4. 使用iText7生成pdf文件

    在写自动生成数据库设计Word文档文章后,朋友建议再实现生成pdf格式,并推荐的iText7,我花了点时间学习了一下itext,实现了这个功能. 首先引入依赖 <dependency>&l ...

  5. android pdfjet_GitHub - lnj721/PdfBuilder: Android端使用图片生成PDF文件

    PdfBuilder Android端使用图片生成PDF文件 一.应用场景 从本地选择图片生成pdf文件,由于Android本身并没有对pdf的支持,这里选择使用一个第三方的库来达成需求. 二.库的选 ...

  6. Android生成pdf文件之PdfDocument及踩过的坑

    有时候项目中可能会遇到这样的需求,如何将android中界面显示的内容生成pdf,这里讲述的是使用android原生的PdfDocument,并没有使用框架,其一是使用起来非常的简单,但是也会也到一些 ...

  7. Itext生成pdf文件,itext+Freemarker生成pdf,(中文空白解决)

    来源:https://my.oschina.net/lujianing/blog/894365 1.背景 在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中转账的电子回单,签约的电子合同等. ...

  8. java 制作pdf模板,Java-pdf模板制作流程-使用pdf 模板生成pdf文件

    Java 使用pdf 模板生成pdf文件 --制作流程 1.      使用工具 adobe acrobat dc.word 2015 2.      使用 word 繪制一個 3*5 的表格並保存, ...

  9. 使用IText7 生成PDF文档

    itext7 生成pdf操作过于复杂,特别是封面.目录页码以及页眉页脚的处理需要基于事件处理,因此写了个简单的类库用于简化操作,只用关注文档内容的构建而无需关注其他: 代码地址: https://gi ...

最新文章

  1. linux下查看网卡型号
  2. server 2008 配置php mysql_Win2008 Server配置PHP环境
  3. Python词云学习之旅
  4. Exchange server 2007 出现“0x8004010F”错误的解决办法
  5. 华为高性能服务器刀箱,云平台服务器刀箱
  6. python怎样导入scrapy_(Python)在导入的模块scrapy中找不到任何项目
  7. 2020年1月1日起,谷歌 Patch Rewards 计划将降低准入门槛,提升开源项目的安全性...
  8. python微控制器编程从零开始 pdf_Python微控制器编程从零开始
  9. 创建自定义Excel模板
  10. BZOJ 3991 set维护dfs序
  11. ubuntu16.04校园网(使用mentohust替代锐捷)
  12. 大数据是人类福音还是洪水猛兽?
  13. 手机图片分辨率怎么调整?如何将图片修改300DPI?
  14. codeblocks错误
  15. 批量nii文件转换为png图像
  16. 基于RV1126 Video分析-----mipi dphy模块所代表的subdev子设备注册
  17. 大数据第一阶段学习笔记
  18. 银行舆情监测怎么做?
  19. 巴伦变压器电路图_巴伦的原理、设计、制作
  20. 基类与派生类中同名成员的关系

热门文章

  1. 【转载】VC++中的图像类型转换--使用开源CxImage类库
  2. y的根号x怎么在计算机里输入,x的平方怎么在电脑上打出来(常见数学符号打法图文)...
  3. AI调参师会被取代吗?对话AutoML初创公司探智立方
  4. OpenCV-矩阵归一化cv::normalize
  5. js跨越问题解决方法
  6. Allegro PCB覆铜的14个注意事项
  7. spring设计好美:WebMvcConfigurer
  8. jq实现模糊搜索文本内容
  9. Django 中间件详解
  10. 浅谈ReentrantLock的公平锁和非公平锁的区别