springboot中使用itext 根据pdf模板导出pdf

博客围绕Spring Boot和iText填充PDF模板展开。介绍了所需背景,包含Spring Boot、iText和做好的PDF模板。给出添加依赖、业务层和控制层代码。还提及碰到的问题,如中文字符串显示不出及模板制作问题,给出相应解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、背景

springboot 、 itext 、做好的pdf模板

2、代码

1、添加依赖
	  <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
      <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.10</version>
      </dependency>

      <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
      <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itext-asian</artifactId>
        <version>5.2.0</version>
      </dependency>
1、业务层代码
@Override
	public File exportReport(String floodForecastingResultId) {

		String newPdfPath = "C:/report.pdf";
		PdfReader reader;
		FileOutputStream out;
		ByteArrayOutputStream bos;
		PdfStamper stamper;
		try{
			File templateFile = ResourceUtils.getFile("classpath:templates/flood1.pdf");
			String templatePath = templateFile.getPath();
			out = new FileOutputStream(newPdfPath);
			reader = new PdfReader(templatePath);// 读取pdf模板
			bos = new ByteArrayOutputStream();
			stamper = new PdfStamper(reader, bos);
			AcroFields form = stamper.getAcroFields();

			//设置显示中文
			BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
			ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
			fontList.add(bf);
			form.setSubstitutionFonts(fontList);

			//处理数据
			WaterForecastRecord waterForecastRecord = waterForecastRecordMapper.selectByRecordId(floodForecastingResultId);


			//String[] str = { "03", "24", "08", "晴", "5", "6", "7", "8", "9","10","11","12","03","24","08","03","24","08","19","20","21","22","23"};
			String[] content = getContentData(waterForecastRecord);
			//String content[] = {"测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试","测试"};
			int i = 0;
			java.util.Iterator<String> it = form.getFields().keySet().iterator();
			while (it.hasNext()) {
				String name = it.next().toString();
				form.setField(name, content[i++]);
			}
			stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为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();
			//System.out.println("文件生成成功");

			return new File(newPdfPath);


		}catch (Exception e){


			e.printStackTrace();
			return null;
		}

	}


说明:floodForecastingResultId为一条记录的id,可以通过这个id 获取数据(由前端传过来),当然,自己造数据也是可以的,
比如上述代码中被注释的“测试”,中文显示不出来的问题代码中也有注释,添加上面相关代码就行,在这个方法中我是根据模板
生成了一个文件返回给控制层 ,由控制层去下载这个文件。
2、控制层代码(文件的下载)
@ApiOperation(value = "导出洪水预报成果pdf",httpMethod = "GET")
	@GetMapping("/export")
	public CommonResult exportPdf(@RequestParam("floodForecastingResultId") String floodForecastingResultId, HttpServletResponse response){
		CommonResult result = ControllerUtil.judgeParamIsNull(floodForecastingResultId);
		if(!Strings.isNullOrEmpty(result.getMessage())){
			return result;
		}
		File file = waterForecastRecordService.exportReport(floodForecastingResultId);

		String fileName = "洪水预报成果记录表.pdf";
		try {
			fileName = java.net.URLEncoder.encode(fileName, "utf-8");// IE11 浏览器
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		response.setContentType("application/force-download");// 设置强制下载不打开
		response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名

		byte[] buffer = new byte[1024];
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		try {
			fis = new FileInputStream(file);
			bis = new BufferedInputStream(fis);
			OutputStream os = response.getOutputStream();
			int i = bis.read(buffer);
			while (i != -1) {
				os.write(buffer, 0, i);
				i = bis.read(buffer);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			file.delete();

		}

		result.setCode(1);
		result.setMessage("导出成功");
		result.setObject(null);

		return result;
	}
3、碰到的问题
1、填充到模板中的中文字符串显示不出来

添加下面代码,这个代码在业务层也有,加到对应的地方就行(参照业务层代码)


//设置显示中文
			BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
			ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
			fontList.add(bf);
			form.setSubstitutionFonts(fontList);
2、模板的制作

用word 制作成表格,在转pdf ,在生成的pdf中编辑表单(不同的pdf 编辑器可能不一样),编辑表单后会有很多框,这个就是填充数据的地方,这个框编辑表单的时候是会自动生成些的,但用自动生成的会有很多问题,最好还是自己添加文字域,并设置字体大小、字体 ,和对齐方式(都在属性设置里面),字体和对齐方式不设置的话都会有一个默认值,具体的可以测试下,还有一个问题就是“m³” 在宋体的字体下,上标3显示不出来,而且导入的数字字体比较粗,经过多次测试“Calibri light”这个字体下数字还是比较细的没有那么粗 “m³”也能显示出来。文字域一定要自己手动添加,一定要自己手动添加,不然问题多多。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值