1.关于java向PDF模板写入数据
参考https://blog.csdn.net/weixin_33875564/article/details/92618051
写的特别全一步一步来就行。
(1)首先下载一个pdf编辑工具Adobe Acrobat DC
(2)准备一个pdf模板文件(你可以把自己创建一个只有表头没有内容的Excel文档来或者一个需要填写内容的Word文档来测试,把文档另存为,保存格式为PDF)
(3)然后使用pdf编辑工具将pdf变成一个准备表单。
(4)然后在你想要添加数据的地方添加文本域,设置文本域名称(标识)。
(5) 首先删除Acrobat DC自动生成的所有的fill控件(单机选中,按delete键删除),因为我发现使用fill控件,Java代码未能成功向模板文件中写入数据。删除之后,在顶部菜单有一个“添加文本域”的控件,点击一下,然后可以拖动控件到下划线上或者冒号后面。可以拖动设置控件大小,双击控件会打开一个对话框,在里面有个名称文本框,可以自定义控件名。如下图:
到目前为止模板文件已经制作完成,下一步开始进行代码编写
(1)引入pom.xml依赖
1 <dependency> 2 <groupId>com.itextpdf</groupId> 3 <artifactId>itextpdf</artifactId> 4 <version>5.5.5</version> 5 </dependency> 6 7 <dependency> 8 <groupId>com.itextpdf</groupId> 9 <artifactId>itext-asian</artifactId> 10 <version>5.2.0</version> 11 </dependency>
(2)Maven引入依赖后,创建测试类。完整代码如下:
import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.*; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * @author aijiao * @date 2018/08/01 */ public class PdfDemo { public static void fillTemplate() { // 模板路径 String templatePath = "E:\工作\模板\模板.pdf"; // 生成的新文件路径 String newPDFPath = "E:\工作\模板\测试.pdf"; PdfReader reader; FileOutputStream out; ByteArrayOutputStream bos; PdfStamper stamper; try { out = new FileOutputStream(newPDFPath); reader = new PdfReader(templatePath); bos = new ByteArrayOutputStream(); stamper = new PdfStamper(reader, bos); AcroFields form = stamper.getAcroFields(); Map<String, String> map = new HashMap<>(); map.put("test1", "中国工商银行"); map.put("test2", "中国农业银行"); map.put("test3", "中国建设银行"); int i = 0; java.util.Iterator<String> it = form.getFields().keySet().iterator(); while (it.hasNext()) { String name = it.next(); form.setField(name, map.get(name)); } //true代表生成的PDF文件不可编辑 stamper.setFormFlattening(true); stamper.close(); Document doc = new Document(); PdfCopy copy = new PdfCopy(doc, out); doc.open(); PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1); copy.addPage(importPage); doc.close(); } catch (IOException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } } public static void main(String[] args) { fillTemplate(); } }
二、java制作pdf报表的问题
参考文章https://blog.csdn.net/qq_40224651/article/details/92764220
https://blog.csdn.net/u013456370/article/details/81481804
https://blog.csdn.net/SHIYUN123zw/article/details/79210119(主要是这个)
1首先使用jaspersoft studio制作模板文件
(1)创建一个项目File -》New -》Project
选择JasperReports Project,点击Next
为自己的项目起个名字,点击Finish
再工具的左上方找到自己刚创建的项目
(2)新建模板xxx.jrxml,取消不需要的band,保留Title,page header, detail1,pagefooder.将组件ta'b'le拖入detail1中。跳蛛dataset窗口,选择create,然后next
给dataset命名。选择create new dateset...,然后next
只保留column header ,然后finish
点击detail中的table组件进入到table界面中。
在column header中邮件column1 选择create column after ,生成四个column
一般表头都是合并列的复杂表头。选择column2邮件。-》group columns
在columns[1]中的column1右键create column after ,显示如下:
在dateset1中新建Field属性,并拖入到table的detail中,设置字体样式(这里自定义命名)注意类型
然后返回到main report ,新建fields 命名为table data,设置class 为JRBeanCollectionDataSource,注意写全路径,新建一个Field为Date,Class为String
(这里主要的作用是将变量存到一个表变量中)(这个table变量是这个table表中所有变量的汇总)
点击main report 的detail 中的table ,显示properties后,点击dataset,选中use 啊 JRDatesource expression,将新建的tableDate写入。
保存模板,并复制到JasperWeb项目中
这个时候模板就弄好了。
然后写代码注入数据源就行。
serviceimpl
/** * 打印pdf报表 * @throws Exception * @throws IO */ @Override public void printZpsStudentTab(String classid, HttpServletRequest req, HttpServletResponse resp) throws Exception { // TODO Auto-generated method stub ZpsClassTabDTO bjDto = zpsClassTabBO.getByClassId(classid); ClassPathResource resource =new ClassPathResource("report/txlist.jasper"); InputStream inputStream=resource.getInputStream(); ServletOutputStream sosRef =resp.getOutputStream(); try { Map<String,Object> hashMap = new HashMap<String,Object>(); hashMap.put("banji", bjDto.getClassname()); List<ZpsStudentTabDTO> list = new ArrayList<ZpsStudentTabDTO>(); List<ZpsStudentTabDO> listT = zpsStudentTabBO.getByClassId(classid); Map map=sayHelloPracticeService.queryTongji("NATION"); List<HashMap> mapnation=(List<HashMap>)map.get("nationlist"); listT.stream().forEach(item -> { ZpsStudentTabDTO dto = new ZpsStudentTabDTO(); ToolUtil.copyProperties(item, dto); mapnation.stream().forEach(nation ->{ if (dto.getNationcode().equals((String)nation.get("val"))) dto.setNationname((String)nation.get("val_name")); }); if (dto.getSex().equals("1")) { dto.setSex("男"); } else { dto.setSex("女"); } dto.setBirthdayt(DateFormatUtils.format(dto.getBirthday(), "yyyy-MM-dd")); list.add(dto); }); resp.setContentType("application/pdf"); ModelTableSource ms = new ModelTableSource(); ms.setTableData(new JRBeanCollectionDataSource(list)); List<ModelTableSource> mlist = new ArrayList<ModelTableSource>(); mlist.add(ms); JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(mlist); // 第三个参数:JavaBean作为数据源,使用JRBeanCollectionDataSource对象来填充 // JasperPrint print = JasperFillManager.fillReport(inputStream, hashMap, dataSource); JasperPrint print = JasperFillManager.fillReport(inputStream, hashMap, dataSource); // 3.使用Exporter导出PDF JasperExportManager.exportReportToPdfStream(print, sosRef); } catch (Exception e) { //log.error(e.toString(), e); throw new ExceptionManager(10111); } finally { sosRef.flush(); sosRef.close(); inputStream.close(); } }
ModelTableSource
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; public class ModelTableSource { private JRBeanCollectionDataSource tableData; private String date; public JRBeanCollectionDataSource getTableData() { return tableData; } public void setTableData(JRBeanCollectionDataSource tableData) { this.tableData = tableData; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } }