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; } }