Android iText向pdf模板插入数据和图片
一、需求
这些日志在写App程序,有这么一个需求,就是需要生成格式统一的一个pdf文件,并向固定表格中填充数据,并且再在pdf中追加两页图片。
二、方案
手工设计一个pdf模板,这个具体步骤就不再赘述,可以网上搜索。说一下模板制作的简单步骤:
1、 用word制作你需要的表单模板
2、 把word制作好的表单模板,另存为pdf格式。
3、 用pdf编辑器(我用的迅捷pdf编辑器),打开pdf,然后进行表单编辑,在需要填充数据的的表格放入文本控件。
4、 另存为pdf模板。
这个模板就是App读取并进行操作的pdf模板,通过这个模板就可以把数据填充到pdf中,并重新生成一个新的pdf文件。
三、下面是代码部分,用到的jar包请看我的其他博文介绍,这里就不再赘述。
android.icu.text.SimpleDateFormat simpleDateFormat =
new android.icu.text.SimpleDateFormat("HHmmss");// HH:mm:ss
//设置默认时区
simpleDateFormat.setTimeZone(android.icu.util.TimeZone.getTimeZone("GMT+8:00"));
//获取当前时间
Date date2 = new Date(System.currentTimeMillis());
String sim2 = simpleDateFormat.format(date2);
String folderName_WaterImage = "WaterImage";
String folderName_WaterDB = "WaterDB";
String folderName_WaterPdf = "WaterPdf";
File sdCardDir_PdfTemplate = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), folderName_WaterDB);
File sdCardDir_WaterPdf = new File(Environment.getExternalStorageDirectory(),
folderName_WaterPdf);
File sdCardDir_WaterImage = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), folderName_WaterImage);
//模板路径
String templatePath = sdCardDir_PdfTemplate + "/" + "WaterTemplate.pdf";
//生成的新文件路径
String newPDFPath = sdCardDir_WaterPdf + "/" +
mWaterInfo.SamplingDate + "_" + mWaterInfo.WellNumber + "_" + sim2 + ".pdf";
String imagePath1 = sdCardDir_WaterImage + "/" + "Image" + id + "_1";
String imagePath2 = sdCardDir_WaterImage + "/" + "Image" + id + "_2";
/**
* 使用中文字体
* 如果是利用 AcroFields填充值的不需要在程序中设置字体,在模板文件中设置字体为中文字体就行了
*/
BaseFont bf = null;
try {
bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Font FontChinese = new Font(bf, 12, Font.NORMAL);
//下面是我需要填充的数据,String格式
String[] strDate = mWaterInfo.SamplingDate.split("-");
String[] str = {
mWaterInfo.WellNumber, mWaterInfo.Longitude + "," + mWaterInfo.Latitude,
strDate[0], strDate[1], strDate[2], mWaterInfo.SamplingTime,
mWaterInfo.SampleMethods, mWaterInfo.SampleDepth, mWaterInfo.Temperature,
mWaterInfo.Weather, mWaterInfo.WaterLevel, mWaterInfo.WaterTemp1,
mWaterInfo.ORP1, mWaterInfo.DO1, mWaterInfo.pH1, mWaterInfo.CT1, mWaterInfo.NTU1,
mWaterInfo.Smell, mWaterInfo.Thing, mWaterInfo.Color, mWaterInfo.SamplingName,
mWaterInfo.RecordingName, mWaterInfo.ReagenInfo, mWaterInfo.bkInfo};
//这个是pdf模板制作时,插入的文本控件名称
String[] it = new String[]{
"Text1", "Text2", "Text3", "Text4", "Text5", "Text6", "Text7",
"Text8", "Text9", "Text10", "Text11", "Text12", "Text13", "Text14", "Text15",
"Text16", "Text17", "Text18", "Text19", "Text20", "Text21", "Text22",
"Text23", "Text24"};
PdfReader reader = new PdfReader(templatePath);//对pdf进行读写
PdfStamper pdfStamper = null;
try {
pdfStamper = new PdfStamper(reader, new FileOutputStream(new File(newPDFPath)));
} catch (DocumentException e) {
e.printStackTrace();
}
AcroFields acroFields = pdfStamper.getAcroFields(); //获取pdf表单
Map<String, String> formData = new HashMap<>();
//formData.put("identify_number", identify.getId_number());
int len = it.length;
//把所有的控件都填入相应的数据
for (int i = 0; i < len; i++) {
acroFields.setFieldProperty(it[i], "textfont", bf, null);
try {
acroFields.setField(it[i], str[i]);
} catch (DocumentException e) {
e.printStackTrace();
}
}
PdfContentByte overContent2 = pdfStamper.getUnderContent(2);//追加一页
PdfContentByte overContent3 = pdfStamper.getUnderContent(3);//追加一页
Image idFontImg2 = Image.getInstance(imagePath1);//获取图片封装对象
Image idFontImg3 = Image.getInstance(imagePath2);//获取图片封装对象
Rectangle rectangleIdFont;
rectangleIdFont = new Rectangle(PageSize.A4.getWidth(), PageSize.A4.getHeight());
//设置图片位置,及缩放
idFontImg2.scaleToFit(rectangleIdFont.getWidth(), rectangleIdFont.getHeight());
idFontImg3.scaleToFit(rectangleIdFont.getWidth(), rectangleIdFont.getHeight());
try {
float x = rectangleIdFont.getLeft();
float y = rectangleIdFont.getBottom();
idFontImg2.setAbsolutePosition(x, y);
idFontImg3.setAbsolutePosition(x, y);
overContent2.addImage(idFontImg2);//将图片添加到pdf
overContent3.addImage(idFontImg3);//将图片添加到pdf
} catch (DocumentException e) {
e.printStackTrace();
}
//addMaterMark(reader, pdfStamper, bfChinese, timeWater);//追加水印
pdfStamper.setFormFlattening(true); //设置表单之后不可编辑
try {
pdfStamper.close();
} catch (DocumentException e) {
e.printStackTrace();
}
reader.close();
Toast.makeText(this, "导出pdf成功", Toast.LENGTH_LONG).show();
四、
程序调试了三四天,中间是各种问题,各种bug,各种报错,终于调试成功。
欢迎交流!
Android iText向pdf模板插入数据和图片的更多相关文章
- C#操作word模板插入文字、图片及表格详细步骤
c#操作word模板插入文字.图片及表格 1.建立word模板文件 person.dot用书签 标示相关字段的填充位置 2.建立web应用程序 加入Microsoft.Office.Interop.W ...
- iText操作pdf(生成,导入图片等)
生成pdf有很多种方法,用pdfbox也很方便,今天我要写的是用iText 主要在pom.xml中配置的jar包如下 <dependency> <groupId>com.low ...
- [转]C#操作word模板插入文字、图片及表格详细步骤
c#操作word模板插入文字.图片及表格 1.建立word模板文件 person.dot用书签 标示相关字段的填充位置 2.建立web应用程序 加入Microsoft.Office.Interop.W ...
- Itext读取PDF模板文件渲染数据后创建新文件
Maven导入依赖 <properties> <itextpdf.version>5.5.0</itextpdf.version> <itext-asian. ...
- 新知识:Java 利用itext填写pdf模板并导出(昨天奋战到深夜四点,知道今天两点终于弄懂)
废话少说,不懂itext干啥用的直接去百度吧. ***************制作模板******************* 1.先用word做出界面 2.再转换成pdf格式 3.用Adobe Acr ...
- 使用poi根据模版生成word文档,支持插入数据和图片
一.制作word模版,${xxxx}是一会要替换的内容,最下面的表格是要插入数据,根据是否以$开头来判断是需要替换还是插入数据, 注意如果是需要插入数据,制作的表格模版需要一行空行,也只能有一行空行, ...
- Android根据pdf模板生成pdf文件
我们需要生成一些固定格式的pdf文件或者一些报表数据,那么我们可以用 iText包去做. 需要包含的jar包:iText-5.0.6.jar iTextAsian.jar ,怎样jar包导入工程 ...
- 不会吧不会吧,还有开发不会Java填充PDF模板数据的,赶紧看看吧
思路 根据业务需求,获取实际业务数据,借助itext库功能,将业务数据填充入提前制作好的PDF模板中 操作步骤 制作PDF模板:提前下载好Adobe Acrobat Pro DC 效果展示 准备PDF ...
- android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本)
原地址 :http://www.cnblogs.com/wangmars/p/3914090.html SQLite,是一款轻型的数据库,被广泛的运用到很多嵌入式的产品中,因为占用的资源非常少,二其中 ...
随机推荐
- java_day03
一.this关键字的作用 昨天学了Java private 关键字 ,private关键字主要是为了 保护变量 ,感觉用着好像并不是特别方便 如果需要访问本类当中的成员变量,需要使用的格式: this ...
- 死磕以太坊源码分析之downloader同步
死磕以太坊源码分析之downloader同步 需要配合注释代码看:https://github.com/blockchainGuide/ 这篇文章篇幅较长,能看下去的是条汉子,建议收藏 希望读者在阅读 ...
- Spring Cloud 2020.0.0正式发布,再见了Netflix
目录 ✍前言 版本约定 ✍正文 Spring Cloud版本管理 与Spring Boot版本对应关系 当前支持的版本 阻断式升级(不向下兼容) 1.再见了,Netflix Netflix组件替代方案 ...
- 获取Web项目中的控制器类以及类中Action方法
前言 在使用时需要修改命名空间.需要过滤控制器.需要过滤Action方法.结果生成表的插入语句. 代码 public ActionResult ReloadData() { #region 获取所有的 ...
- setHeader方法的参数说明
转自:http://blog.sina.com.cn/s/blog_510fdc8b0100v8sg.html response.setHeader 是用来设置返回页面的头 meta 信息, 使用时 ...
- VNC使用及其常见问题解决方法
博主之前在博文(https://www.cnblogs.com/kangbazi666/p/14153604.html)中已经介绍了多人VNC的配置方法,下面将简单介绍其使用方法及常见问题的解决方法. ...
- 在.NET Core中使用Channel(一)
我最近一直在熟悉.net Core中引入的新Channel<T>类型.我想在它第一次发布的时候我了解过它,但是有关文章非常非常少,我不能理解它们与其他队列有什么不同. 在使用了一段时间后, ...
- vue element 表单验证不通过,滚动到固对应位置
我们在使用elementIUI实现表单验证,内容比较多的时候,提示内容会被遮挡,这时候用户不清楚什么情况,还会连续点击提交按钮.这个时候需求来啦:我们需要在表单验证不通过的时候,页面滚动到对应的位置. ...
- vue 过滤器 filter 的使用
1.局部过滤器的使用 比如性别,订单状态的数据,后端一般返回数字来代替状态.以性别为模拟数据,0是未知,1是男,2是女. 直接数据渲染出来,只有012,没有性别 根据后端返回的int类型值,前端对数据 ...
- 多年经验总结,写出最惊艳的 Markdown 高级用法
点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...