JAVA按模版导出PDF文件,含条码,二维码,表格

示例模版:

示例导出:

核心代码:

package com.yonyou.dms.framework.service.pdf;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.AcroFields.FieldPosition;
import com.itextpdf.text.pdf.Barcode39;
import com.itextpdf.text.pdf.BarcodeQRCode;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.yonyou.dms.framework.service.pdf.domain.PDFTableDto;

/**
 * @ClassName: PDFTemplateExport
 * @Description: TODO
 * @Author: xiongrx@vip.qq.com
 * @Date: 2017年8月26日
 */
public class PDFTemplateExport {
	
	private static final Logger logger = LoggerFactory.getLogger(PDFTemplateExport.class);

	private String templatePdfPath;
	private String fontName = "simsun.ttc,1";

	public PDFTemplateExport(String templatePdfPath) {
		this.templatePdfPath = templatePdfPath;
	}

	public PDFTemplateExport(String templatePdfPath, String fontName) {
		this.templatePdfPath = templatePdfPath;
		this.fontName = fontName;
	}

	/**
	 * 根据模版导出PDF文档
	 * @param os 输出流
	 * @param textFields 文本字段
	 * @param barcodeFields 条码字段
	 * @param qrcodeFields 二维码字段
	 * @param tableFields 表格字段
	 * @throws Exception
	 */
	public void export(OutputStream os, Map<String, Object> textFields, Map<String, Object> barcodeFields, Map<String, Object> qrcodeFields,Map<String, PDFTableDto> tableFields) throws Exception {
		//读取模版
		PdfReader reader = new PdfReader(templatePdfPath);
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		PdfStamper ps = new PdfStamper(reader, bos);

		//使用中文字体
		BaseFont bf = BaseFont.createFont(getFontPath(fontName), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
		ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
		fontList.add(bf);

		AcroFields s = ps.getAcroFields();
		s.setSubstitutionFonts(fontList);
		
		//遍历表单字段
		for (Map.Entry<String, Object> entry : textFields.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			
			s.setFieldProperty(key, "textfont", bf, null);
    		s.setField(key, getBlank(value));
		}
    	
    	//遍历条码字段
		for (Map.Entry<String, Object> entry : barcodeFields.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			// 获取属性的类型
			if(value != null && s.getField(key) != null){
				//获取位置(左上右下)
				FieldPosition fieldPosition = s.getFieldPositions(key).get(0);
				//绘制条码
				Barcode39 barcode39 = new Barcode39();
				//字号
				barcode39.setSize(12);
				//条码高度
				barcode39.setBarHeight(30);
				//条码与数字间距
				barcode39.setBaseline(10);
				//条码值
				barcode39.setCode(value.toString());
				barcode39.setStartStopText(false);
				barcode39.setExtended(true);
				//绘制在第一页
				PdfContentByte cb = ps.getOverContent(1);
				//生成条码图片
				Image image128 = barcode39.createImageWithBarcode(cb, null, null);
				//左边距(居中处理)
				float marginLeft = (fieldPosition.position.getRight() - fieldPosition.position.getLeft() - image128.getWidth()) / 2;
				//条码位置
				image128.setAbsolutePosition(fieldPosition.position.getLeft() + marginLeft, fieldPosition.position.getBottom());
				//加入条码
				cb.addImage(image128);
			}
		}
		
		//遍历二维码字段
		for (Map.Entry<String, Object> entry : qrcodeFields.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			// 获取属性的类型
			if(value != null && s.getField(key) != null){
				//获取位置(左上右下)
				FieldPosition fieldPosition = s.getFieldPositions(key).get(0);
				//绘制二维码
				float width = fieldPosition.position.getRight() - fieldPosition.position.getLeft();
				BarcodeQRCode pdf417 = new BarcodeQRCode(value.toString(), (int)width, (int)width, null);
				//生成二维码图像
				Image image128 = pdf417.getImage();
				//绘制在第一页
				PdfContentByte cb = ps.getOverContent(1);
				//左边距(居中处理)
				float marginLeft = (fieldPosition.position.getRight() - fieldPosition.position.getLeft() - image128.getWidth()) / 2;
				//条码位置
				image128.setAbsolutePosition(fieldPosition.position.getLeft() + marginLeft, fieldPosition.position.getBottom());
				//加入条码
				cb.addImage(image128);
			}
		}
		
		//遍历表格字段
		Font keyfont = new Font(bf, 8, Font.BOLD);// 设置字体大小 
		Font textfont = new Font(bf, 8, Font.NORMAL);// 设置字体大小 
		for (Map.Entry<String, PDFTableDto> entry : tableFields.entrySet()) {
			String key = entry.getKey();
			PDFTableDto tableDto = entry.getValue();
			// 获取属性的类型
			if(tableDto != null && tableDto.getColFields() != null && s.getField(key) != null){
				//获取位置(左上右下)
				FieldPosition fieldPosition = s.getFieldPositions(key).get(0);
				float width = fieldPosition.position.getRight() - fieldPosition.position.getLeft();
				//创建表格
				String[] thread = tableDto.getColNames() != null ? tableDto.getColNames().split(",") : tableDto.getColFields().split(",");
				PdfPTable table = new PdfPTable(thread.length);
		        try{ 
		            table.setTotalWidth(width); 
		            table.setLockedWidth(true); 
		            table.setHorizontalAlignment(Element.ALIGN_CENTER);      
		            table.getDefaultCell().setBorder(1); 
		        }catch(Exception e){
		            e.printStackTrace(); 
		        }
		        //创建表头
				for (String col : thread) {
					table.addCell(createCell(col, keyfont, Element.ALIGN_CENTER));
				}
				//创建表体
				String[] fields = tableDto.getColFields().split(",");
				List<Map<String, Object>> dataList = tableDto.getDataList();
				if(dataList != null && dataList.size() > 0){
					for(int i=0;i<dataList.size();i++){
						Map<String, Object> row = dataList.get(i);
						for (String field : fields) {
							table.addCell(createCell(row.get(field), textfont));
						}
					}
				}
		        //插入文档
		        PdfContentByte cb = ps.getOverContent(1);
		        table.writeSelectedRows(0, -1, 0, -1, fieldPosition.position.getLeft(), fieldPosition.position.getTop(), cb);
			}
		}

		ps.setFormFlattening(true);
		ps.close();
		
		os.write(bos.toByteArray());
		os.flush();
		os.close();
		
		bos.close();
		reader.close();
	}
	
	/**
	 * 创建单元格
	 * @param value 显示内容
	 * @param font 字体
	 * @param align 对齐方式
	 * @return
	 */
	private static PdfPCell createCell(Object value, Font font, int align) {
		PdfPCell cell = new PdfPCell();
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(align);
		cell.setPhrase(new Phrase(getBlank(value), font));
		return cell;
	}

	/**
	 * 创建单元格
	 * @param value 显示内容
	 * @param font 字体
	 * @return
	 */
	private static PdfPCell createCell(Object value, Font font) {
		PdfPCell cell = new PdfPCell();
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setPhrase(new Phrase(getBlank(value), font));
		return cell;
	}
	
	/**
	 * 非空处理
	 * @param value
	 * @return
	 */
	private static String getBlank(Object value) {
		if(value != null){
			return value.toString();
		}
		return "";
	}
	
	/**
	 * 获取字体文件
	 * @param fontName
	 * @return
	 */
	private String getFontPath(String fontName) {
		String fontPath = "C:\\Windows\\Fonts\\" + fontName;

		// 判断系统类型,加载字体文件
		java.util.Properties prop = System.getProperties();
		String osName = prop.getProperty("os.name").toLowerCase();
		if (osName.indexOf("linux") > -1) {
			fontPath = "/usr/share/fonts/" + fontName;
		}
		return fontPath;
	}
	
	public static void main(String[] args) throws Exception {
		File outputFile = new File("C:\\Users\\XiongRx\\Desktop\\export.pdf");
		Map<String, Object> textFields = new HashMap<String, Object>();
		textFields.put("ifCode", "ZC-TXJ-01");
		textFields.put("ifName", "获取单台或多台车实时位置及油耗数据");
		textFields.put("ifSource", "天行健");
		textFields.put("ifFrequency", "实时");
		textFields.put("ifType", "WebService");
		textFields.put("ifDesc", "当整车系统需要获取某台或多台车的实时位置时,即可实时调用此接口获取所查询车辆的坐标数据、油耗数据等");

		Map<String, Object> barcodeFields = new HashMap<String, Object>();
		barcodeFields.put("ifLogic", "12312312312");
		
		Map<String, Object> qrcodeFields = new HashMap<String, Object>();
		qrcodeFields.put("qrCode", "http://blog.csdn.net/ruixue0117/article/details/77599808");
		
		PDFTableDto tableDto = new PDFTableDto();
		tableDto.setColNames("第1列,第2列,第3列,第4列,第5列");
		tableDto.setColFields("col1,col2,col3,col4,col5");
		List<Map<String, Object>> dataList = new ArrayList<Map<String,Object>>();
		for(int i=0;i<15;i++){
			Map<String, Object> row = new HashMap<String, Object>();
			for(int j=1;j<5;j++){
				row.put("col"+j, "col"+j);
			}
			dataList.add(row);
		}
		tableDto.setDataList(dataList);
		Map<String, PDFTableDto> tableFields = new HashMap<String, PDFTableDto>();
		tableFields.put("table", tableDto);
		
		outputFile.createNewFile();
		new PDFTemplateExport("C:\\Users\\XiongRx\\Desktop\\Simple1.pdf").export(new FileOutputStream(outputFile), textFields, barcodeFields, qrcodeFields, tableFields);
	}
}

调用方法:

package com.yonyou.dms.framework.service.pdf.impl;

import java.io.File;
import java.io.OutputStream;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.yonyou.dms.framework.service.pdf.PDFTemplateExport;
import com.yonyou.dms.framework.service.pdf.PdfGenerator;
import com.yonyou.dms.framework.service.pdf.domain.PDFGeneratorDto;
import com.yonyou.dms.framework.service.pdf.domain.PDFTableDto;
import com.yonyou.dms.function.exception.ServiceBizException;
import com.yonyou.dms.function.exception.UtilException;
import com.yonyou.dms.function.utils.common.CommonUtils;
import com.yonyou.dms.function.utils.common.StringUtils;
import com.yonyou.dms.function.utils.io.IOUtils;

@Component
public class PdfGeneratorDefaultImpl implements PdfGenerator {

	// 定义日志接口
	private static final Logger logger = LoggerFactory.getLogger(PdfGeneratorDefaultImpl.class);

	/**
	 * 生成Pdf文件到下载输出流
	 * @param generator
	 * @param request
	 * @param response
	 */
	@Override
	public void generatePdf(@SuppressWarnings("rawtypes") PDFGeneratorDto generator, HttpServletRequest request, HttpServletResponse response) {
		// 如果Data中没有数据,则返回错误
		if (generator == null || StringUtils.isNullOrEmpty(generator.getTempPath()) || CommonUtils.isNullOrEmpty(generator.getTextFields())) {
			throw new ServiceBizException("No Pdf Data !");
		}

		OutputStream outputStream = null;
		PDFTemplateExport pdfExport = null;
		try {
			// 初始化输出流
			String fileName = StringUtils.getString(generator.getFileName(), UUID.randomUUID());
			outputStream = initOutputStream(request, response, fileName, generator.isOnlineView());
			// 初始化模版
			String fontPath = StringUtils.getString(generator.getFontPath());
			String tempPath = StringUtils.getString(generator.getTempPath());
			String rootDir = request.getSession().getServletContext().getRealPath("/");
			tempPath = rootDir + "assets" + File.separator + "pdf" + File.separator + tempPath;
			if (StringUtils.isNullOrEmpty(fontPath)) {
				pdfExport = new PDFTemplateExport(tempPath);
			} else {
				pdfExport = new PDFTemplateExport(tempPath, fontPath);
			}
			// 写入数据
			Map<String, Object> textFields = generator.getTextFields();
			Map<String, Object> barcodeFields = generator.getBarcodeFields();
			Map<String, Object> qrcodeFields = generator.getQrcodeFields();
			Map<String, PDFTableDto> tableFields = generator.getTableFields();
			pdfExport.export(outputStream, textFields, barcodeFields, qrcodeFields, tableFields);
		} catch (Exception exception) {
			logger.warn(exception.getMessage(), exception);
			throw new ServiceBizException(exception.getMessage(), exception);
		} finally {
			IOUtils.closeStream(outputStream);
		}
	}

	/**
	 * 初始化输出流
	 * @param request
	 * @param response
	 * @param fileName
	 * @param isOnLine
	 * @return
	 * @throws UtilException
	 */
	private OutputStream initOutputStream(HttpServletRequest request, HttpServletResponse response, String fileName, boolean isOnLine) throws UtilException {
		try {
			// 中文文件名兼容性调整
			String enableFileName = "";
			String agent = (String) request.getHeader("USER-AGENT");
			if (agent != null && agent.indexOf("like Gecko") != -1) {// IE11
				enableFileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
			}else if (agent != null && agent.indexOf("MSIE") == -1) {// FF
				enableFileName = "=?UTF-8?B?" + (new String(Base64.encodeBase64(fileName.getBytes("UTF-8")))) + "?=";
			} else { // IE
				enableFileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
			}

			// 输出文件流
			response.reset(); // 非常重要
			if (isOnLine) { // 在线打开方式
				response.setContentType("application/pdf");
				response.setHeader("Content-Disposition", "inline; filename=" + enableFileName);
			} else { // 纯下载方式
				response.setContentType("application/x-msdownload");
				response.setHeader("Content-Disposition", "attachment; filename=" + enableFileName);
			}
			return response.getOutputStream();
		} catch (Exception e) {
			throw new UtilException("pdf 流初始化失败", e);
		}
	}
}
package com.yonyou.dms.framework.service.pdf.domain;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * PDF模版信息
 * @author XiongRx
 * @date 2017年7月19日
 */
public class PDFGeneratorDto {

    private String tempPath;
    private String fontPath;
    private Map<String, Object> textFields = new HashMap<String, Object>();
    private Map<String, Object> barcodeFields = new HashMap<String, Object>();
    private Map<String, Object> qrcodeFields = new HashMap<String, Object>();
    private Map<String, PDFTableDto> tableFields = new HashMap<String, PDFTableDto>();
    
    private String fileName;
    private boolean onlineView = false;
    
	public String getTempPath() {
		return tempPath;
	}
	public void setTempPath(String tempPath) {
		this.tempPath = tempPath;
	}
	public String getFontPath() {
		return fontPath;
	}
	public void setFontPath(String fontPath) {
		this.fontPath = fontPath;
	}
	public Map<String, Object> getTextFields() {
		return textFields;
	}
	public void setTextFields(Map<String, Object> textFields) {
		this.textFields = textFields;
	}
	public Map<String, Object> getBarcodeFields() {
		return barcodeFields;
	}
	public void setBarcodeFields(Map<String, Object> barcodeFields) {
		this.barcodeFields = barcodeFields;
	}
	public Map<String, Object> getQrcodeFields() {
		return qrcodeFields;
	}
	public void setQrcodeFields(Map<String, Object> qrcodeFields) {
		this.qrcodeFields = qrcodeFields;
	}
	public Map<String, PDFTableDto> getTableFields() {
		return tableFields;
	}
	public void setTableFields(Map<String, PDFTableDto> tableFields) {
		this.tableFields = tableFields;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public boolean isOnlineView() {
		return onlineView;
	}
	public void setOnlineView(boolean onlineView) {
		this.onlineView = onlineView;
	}
    
}
package com.yonyou.dms.framework.service.pdf.domain;

import java.util.List;
import java.util.Map;

/**
 * PDF表格信息
 * @author XiongRx
 * @date 2017年7月19日
 */
public class PDFTableDto {

    private String colNames;
    private String colFields;
    private List<Map<String, Object>> dataList;
    
	public String getColNames() {
		return colNames;
	}
	public void setColNames(String colNames) {
		this.colNames = colNames;
	}
	public String getColFields() {
		return colFields;
	}
	public void setColFields(String colFields) {
		this.colFields = colFields;
	}
	public List<Map<String, Object>> getDataList() {
		return dataList;
	}
	public void setDataList(List<Map<String, Object>> dataList) {
		this.dataList = dataList;
	}
    
    
}

相关JAR包:

<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itextpdf</artifactId>
	<version>5.5.10</version>
</dependency>
<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itext-asian</artifactId>
	<version>5.2.0</version>
</dependency>

还是写点备注吧:

这个代码重要的不是模版也不是条码(满大街都是),是在模版里设置条码和表格的位置。

实现按格式导出只需要核心代码就够了,写了个调用工具类是因为核心方法的参数较多,不方便调用,再者写了个实体类后续有新增需求也好维护,加新属性就好了,不会影响已有的调用。

http://rensanning.iteye.com/blog/1538689

附上很全的参考资料,并表示感谢。

已上传实例

https://download.csdn.net/download/ruixue0117/21420308

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
根据提供的引用内容,可以使用Java实现根据模板生成并导出PDF的功能。具体步骤如下: 1.使用JavaPDF库,例如iText或Apache PDFBox,读取PDF模板文件。 2.使用模板文件中的参数,填充PDF表单字段或者在PDF页面上添加文本、图片等内容。 3.将填充后的PDF文件导出到指定的路径。 下面是一个使用iText库实现根据模板导出PDF的示例代码: ```java import com.itextpdf.text.Document; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import java.io.FileOutputStream; import java.util.Map; public class PdfGenerator { public static void generatePdf(String templatePath, String outputPath, Map<String, String> params) throws Exception { // 读取PDF模板文件 PdfReader reader = new PdfReader(templatePath); // 创建输出流 FileOutputStream fos = new FileOutputStream(outputPath); // 创建PDF文档对象 Document document = new Document(); // 创建PDF写入器 PdfCopy copy = new PdfCopy(document, fos); // 打开文档 document.open(); // 填充PDF表单字段 PdfStamper stamper = new PdfStamper(reader, fos); for (Map.Entry<String, String> entry : params.entrySet()) { stamper.getAcroFields().setField(entry.getKey(), entry.getValue()); } stamper.setFormFlattening(true); stamper.close(); // 将填充后的PDF文件导出到指定的路径 for (int i = 1; i <= reader.getNumberOfPages(); i++) { PdfImportedPage page = copy.getImportedPage(new PdfReader(reader), i); copy.addPage(page); } document.close(); reader.close(); fos.close(); } } ``` 其中,`templatePath`为PDF模板文件的路径,`outputPath`为导出PDF文件的路径,`params`为填充PDF表单字段的参数。可以根据实际需求修改代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值