Android 内容生成pdf文件

news2025/5/26 1:15:42
1.引入itext7
implementation 'com.itextpdf:itext7-core:7.1.13'

上面比较大,可以直接下载需要集成的jar包
implementation files('libs\\layout-7.1.13.jar')
implementation files('libs\\kernel-7.1.13.jar')
implementation files('libs\\io-7.1.13.jar')
implementation files('libs\\slf4j-android-1.6.1-RC1.jar')
import android.graphics.Bitmap
import android.os.Environment
import com.itextpdf.io.image.ImageDataFactory
import com.itextpdf.kernel.font.PdfFontFactory
import com.itextpdf.kernel.geom.PageSize
import com.itextpdf.kernel.pdf.PdfDocument
import com.itextpdf.kernel.pdf.PdfWriter
import com.itextpdf.layout.Document
import com.itextpdf.layout.borders.Border
import com.itextpdf.layout.element.Cell
import com.itextpdf.layout.element.Image
import com.itextpdf.layout.element.Paragraph
import com.itextpdf.layout.element.Table
import com.itextpdf.layout.property.HorizontalAlignment
import com.itextpdf.layout.property.TextAlignment
import com.itextpdf.layout.property.UnitValue
import com.itextpdf.layout.property.VerticalAlignment
import com.thinkerjet.jdcommunication.appbase.BaseActivity
import java.io.ByteArrayOutputStream
import java.util.*
import java.util.concurrent.Executors

class PdfUitl {
    companion object {
        val sIntance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            PdfUitl()
        }

        public interface SavePdfInterface {
            fun savePdf(path: String);
        }

        lateinit var savePdfInterface: SavePdfInterface

    }

    fun createPdf(activity: BaseActivity, bitmap: Bitmap) {
        try {
            //创建一个 PdfWriter 对象,用于将文档写入到 PDF 文件中
            var writer: PdfWriter =
                PdfWriter(activity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).absolutePath + "/agreement.pdf")
            //创建一个 PdfDocument 对象,表示 PDF 文档
            val pdfDoc = PdfDocument(writer)
            //指定 PDF 中文本的字体和编码
            val pdfFont = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H")
            //创建一个 Document 对象,表示 PDF 文档的页面  A4 大小
                val document = Document(pdfDoc, PageSize.A4)
            val paraTitle = "【客户信息安全保护承诺书】"
            val paraInfoTop =
                "***************公司: 为依法做好用户个人信息保护,切实保障人民群众合法权益,促进通信行业健康发展,维护国家安全和社会稳定,我公司及个人做出郑重承诺: 严格按照《电信和互联网用户个人信息保护规定》(工信部第24号令)、《中华人民共和国网络安全法》等法律法规的要求,以及贵公司相关管理规定,落实好用户个人信息保护工作,杜绝发生非法获取个人信息,以及非法使用、提供、销售个人信息的行为,严禁超范围、超界限使用。"
            val paraInfoMiddle =
                "在工作及为用户提供服务过程中,未经公司明确授权,不得自行或与第三方进行合作开展任何营销活动;未经公司明确授权,不得在未向用户告知活动详细规则的情况下,通过劝说、引诱等方式要求客户提供信息(包括但不限于手机号、身份证号、短信验证码等),从事为客户注册互联网账号等违规行为;任何处理(包括收集、注册等)客户手机号码等个人信息的行为,均应当严格按照公司的有关规章制度办理,不得超越权限处理。"
            val paraInfoBottom =
                "在执行中如有出现违反用户个人信息保护等工作的要求,或者存在隐瞒不报、包庇袒护的行为,视作严重违规,将按贵公司社会渠道管理办法及相关规定接受相应处罚,并对公司内部人员及渠道营业人员进行从严处理,涉嫌犯罪的依法移送司法机关。\n"
            val paraCompany = "承诺单位名称(盖章)"
            val paraPeople = "承诺人签字"
            val cd: Calendar = Calendar.getInstance()
            val paraDate = cd.get(Calendar.YEAR)
                .toString() + "年" + (cd.get(Calendar.MONTH) + 1).toString() + "月" + cd.get(Calendar.DATE)
                .toString() + "日"
            document.setFont(pdfFont)
            document.setFontSize(JnUtils.dp2px(activity, 8f).toFloat())
            //创建段落
            val paragraphTitle = Paragraph(paraTitle)
            //文字居中
            paragraphTitle.setTextAlignment(TextAlignment.CENTER)
            //创建段落
            val paragraphTop = Paragraph(paraInfoTop)
            //创建段落
            val paragraphMiddle = Paragraph(paraInfoMiddle)
            paragraphMiddle.setBold()
            //单倍行距
            paragraphMiddle.setMultipliedLeading(1f)

            val paragraphBottom = Paragraph(paraInfoBottom)
            val paragraphCompany = Paragraph(paraCompany)
            paragraphCompany.setTextAlignment(TextAlignment.RIGHT)
            val paragraphPeople = Paragraph(paraPeople)
            paragraphPeople.setTextAlignment(TextAlignment.RIGHT)

            val paragraphDate = Paragraph(paraDate)
            //添加到pdf
            document.add(paragraphTitle)
            document.add(paragraphTop)
            document.add(paragraphMiddle)
            document.add(paragraphBottom)
            document.add(paragraphCompany)

           //这个数组用于存储后续用于创建表格的列宽度信息
            val resultArray = arrayOfNulls<UnitValue>(2)
            //第一列的宽度将占据表格可用宽度的 190%。
            resultArray[0] = UnitValue.createPercentValue(190f)
            //第二列的宽度将占据表格可用宽度的 200%。
            resultArray[1] = UnitValue.createPercentValue(200f)
            //方法用于使表格使用所有可用的宽度,确保表格填满水平空间。
            val table = Table(resultArray).useAllAvailableWidth()
            //表格的总宽度为 390 点
            table.setWidth(390f)
            table.setHorizontalAlignment(HorizontalAlignment.RIGHT)
            Executors.newSingleThreadExecutor().execute(object : Runnable {
                override fun run() {
                    //创建了一个字节数组输出流 baos,用于临时存储图像数据。
                    val baos = ByteArrayOutputStream()
                    //以 JPEG 格式、质量为 100% 的压缩率写入到输出流 baos 中
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
                    //创建iText 7 PDF 的图像对象
                    val image = Image(ImageDataFactory.create(baos.toByteArray()))
                    image.setWidth(80f)
                    image.setHeight(35f)
                    //1 行 1 列包含一个段落对象 paragraphPeople的单元格
                    val cellPeople: Cell = Cell(1, 1).add(paragraphPeople)
                    cellPeople.setTextAlignment(TextAlignment.RIGHT)
                    cellPeople.setVerticalAlignment(VerticalAlignment.BOTTOM)
                    cellPeople.setBorder(Border.NO_BORDER)
                    //单元格添加到之前创建的表格 table 中,并设置其边框为无边框
                    table.addCell(cellPeople).setBorder(Border.NO_BORDER)
                    //表格添加1 行 2 列包含图像的单元格
                    table.addCell(Cell(1, 2).setBorder(Border.NO_BORDER).add(image))

                    //2行 1 列包含时间的单元格
                    val cellData: Cell = Cell(2, 1).setBorder(Border.NO_BORDER).add(paragraphDate);
                    cellData.setVerticalAlignment(VerticalAlignment.BOTTOM)
                    cellData.setTextAlignment(TextAlignment.RIGHT)
                    table.addCell(cellData)
                    //将table 添加到PDF文档中
                    document.add(table)
                    //关闭 PDF 文档,完成文档的创建
                    document.close()
                    //回收bitmap的资源,释放内存
                    bitmap.recycle()
                    savePdfInterface?.savePdf(activity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).absolutePath + "/agreement.pdf")
                }
            })
        } catch (e: Exception) {
            savePdfInterface?.savePdf("")
            e.printStackTrace()
        }


    }


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1355718.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《MySQL系列-InnoDB引擎04》MySQL表相关介绍

文章目录 第四章 表1 索引组织表2 InnoDB逻辑存储结构2.1 表空间2.2 段2.3 区2.4 页2.5 行2.6 拓展&#xff1a;MySQL的varchar(n)能存储几个字符&#xff1f;占多少字节&#xff1f; 3 InnoDB行记录格式4 文件格式5 约束5.1 数据完整性5.2 约束的创建和查找5.3 约束和索引的区…

如何为项目创建高效的项目进度表?

项目管理是一项负有巨大责任的工作&#xff0c;涉及到完成项目所需的大量流程和任务。如果没有任务和责任的线路图&#xff0c;很容易就偏离方向&#xff0c;无法了解项目每个阶段需要完成的任务。这就是为什么项目进度表是成功执行项目的核心所在。 什么是项目进度表&#xff…

数据分析-24-母婴产品电商可视化分析(包含代码数据)

文章目录 0. 代码数据获取1. 项目1.1 项目介绍1.2 分析目的1.3 分析思路 2. 数据集介绍2.1 数据信息2.2 字段含义 3. 数据清洗3.1 导入包和查看数据3.2 查看列的信息3.3 查看表平均值这些3.4 查出重复的user_id3.5 清洗buy_mount列 4. 针对目的进行分析4.1 销量数量前10的类别I…

T40N 君正智能处理器T40 BGA 芯片

T40N是一款智能视频应用处理器&#xff0c;适用于移动摄像机、安防等视频设备调查、视频聊天、视频分析等。该SoC引入了一种创新的体系结构满足高性能计算和高质量图像和视频编码的要求通过视频设备解决。T40N提供高速CPU计算能力&#xff0c;出色的图像信号过程中&#xff0c;…

ensp vlan连接(详细)

1.将需要的设备放置好 2.将设备连接起来 3.启动所有设备 4.备注好每台PC机的信息 5.配置好每台PC机 6.配置交换机1 进入配置视图&#xff0c;关闭信息提示 重命名设备 批量创建VLAN 开始配置接口 更改接口类型为ACCESS 将接口划分到对应的VLANN 配置下一个接口&#xff0c;步…

JavaScript高级程序设计读书记录(一):语言基础,语法,变量,数据类型

1. 语法 很大程度上借鉴了 C 语言和其他类 C 语言&#xff0c;如 Java 和 Perl. 1.1 区分大小写 1.2 标识符 第一个字符必须是一个字母、下划线&#xff08;_&#xff09;或美元符号&#xff08;$&#xff09;&#xff1b; 剩下的其他字符可以是字母、下划线、美元符号或数…

qiankun 公共依赖

1、提取公共依赖的目的 减少相同资源的重复加载资源版本不同步打包文件庞大2、如何提取公共依赖 基本思路&#xff1a;1、相同依赖 采用 CDN 的方式加载&#xff0c;并把 所有依赖的 CDN 链接 统一放到一个文件中进行管理 2、把存放 CDN 链接的文件&#xff0c;引入到 vue.conf…

NFT 项目入驻 NFTScan Site 流程说明

NFTScan Site 是由数据基础设施 NFTScan 推出的功能强大的 NFT 项目管理平台。NFTScan Site 主要为 NFT Collection、NFT Marketplace、NFTFi 以及其他 NFT 生态项目提供专业的项目管理后台服务和链上数据分析追踪服务。 NFTScan Site 功能&#xff1a; 1&#xff09;项目信息编…

华硕ASUS RT-AC1200 pandavan老毛子 128M DDR固件

原版硬件只支持64M DDR2&#xff0c;更换了128M内存&#xff0c;结果找不到对应的固件&#xff0c;而且全部都是英文版的 所以自己编译了中文版的pandavan老毛子&#xff0c;下载位置可能资源审核中&#xff1a;

基于Kettle开发的web版数据集成开源工具(data-integration)-部署篇

目录 &#x1f4da;第一章 前言&#x1f4d7;背景&#x1f4d7;目的&#x1f4d7;总体方向 &#x1f4da;第二章 下载编译&#x1f4d7;下载&#x1f4d7;编译 &#x1f4da;第三章 部署&#x1f4d7;准备工作&#x1f4d5; 安装数据库&redis&consul&#x1f4d5; 修改…

树莓派控制继电器(IO的配置和使用)

一、硬件函数初始化 int wiringPiSetup(void)返回&#xff1a;执行状态&#xff0c;-1表示失败 当使用这个函数初始化树莓派引脚时&#xff0c;程序使用的是wiringPi 引脚编号表。引脚的编号为 0~16 需要root权限 二、配置IO口的模式 void pinMode (int pin, int …

算法31:针对算法30货币问题进行拓展 + 时间复杂度 + 空间复杂度优化--------从左往右尝试模型

在算法30中&#xff0c;我们说过从左往右尝试模型&#xff0c;口诀就是针对固定集合&#xff0c;就是讨论要和不要的累加和。 那么对于非固定集合&#xff0c;我们应该怎么做呢&#xff1f; 针对非固定集合&#xff0c;面值固定&#xff0c;张数不固定。口诀就是讨论要与不要…

URLConnection()和openStream()两个方法产生SSRF的原理和修复方法

今年是自主研发的第三个年份&#xff0c;也是重视安全的年份。 转一篇小文章&#xff1a; 0x00 前言 SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定 URL 地址获取网页文本内容&#xff0c;加载指定地址的图…

《算法导论》复习——CHP1、CHP2 算法基础

基本定义&#xff1a; 算法是一组有穷的规则&#xff0c;规定了解决某一特定类型问题的一系列运算。 关心算法的正确性和效率。 算法的五个重要特性&#xff1a;确定性、能行性、输入、输出、有穷性。 基础方法&#xff1a; 伪代码&#xff08;Pseudocode&#xff09;&#xff…

C# .Net学习笔记—— 异步和多线程(Task)

一、概念 Task是DotNet3.0之后所推出的一种新的使用多线程的方式&#xff0c;它是基于ThreadPool线程进行封装的。 二、使用多线程的时机 任务能够并发运行的时候&#xff0c;提升速度&#xff1b;优化体验 三、基本使用方法 private void button5_Click(object sender, Ev…

Spark内核解析-数据存储5(六)

1、Spark的数据存储 Spark计算速度远胜于Hadoop的原因之一就在于中间结果是缓存在内存而不是直接写入到disk&#xff0c;本文尝试分析Spark中存储子系统的构成&#xff0c;并以数据写入和数据读取为例&#xff0c;讲述清楚存储子系统中各部件的交互关系。 1.1存储子系统概览 …

RT-Thread 14. GD32F330RBT6 Keil4移植RT-Thread

1.增加rt-thread-v4.1.0源码 rt-thread-v4.1.0\bsp\gd32350r-eval复制重命名为gd32f330_v1 2.文件组织结构 Usr&#xff1a;存放App任务应用&#xff0c;属于应用层&#xff0c;完全脱离硬件 CMSIS&#xff1a;硬件层&#xff0c;启动文件、系统文件 Driver&#xff1a;硬件外…

Spring实现IoC:依赖注入/构造注入

● 控制反转&#xff0c;反转的是什么&#xff1f; ○ 将对象的创建权利交出去&#xff0c;交给第三方容器负责。 ○ 将对象和对象之间关系的维护权交出去&#xff0c;交给第三方容器负责。 ● 控制反转这种思想如何实现呢&#xff1f; ○ DI&#xff08;Dependency Injection&…

通过IP地址如何进行网络安全防护

IP地址在网络安全防护中起着至关重要的作用&#xff0c;可以用于监控、过滤和控制网络流量&#xff0c;识别潜在威胁并加强网络安全。以下是通过IP地址进行网络安全防护的一些建议&#xff1a; 1. 建立IP地址白名单和黑名单&#xff1a; 白名单&#xff1a;确保只有授权的IP地…

UMLChina书籍大全(2024)软件方法人月神话人件企业应用架构模式UML参考手册彩色UML建模领域驱动设计对象设计……

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 以下列出有UMLChina标记的书。 首先是写了十几年还没有写完的软件方法 其他的是译作&#xff1a; 人月神话 2002年&#xff0c;UMLChina和清华大学出版社合作&#xff0c;翻译了《人…