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

示例模版:

JAVA按模版导出PDF文件,含条码,二维码,表格_第1张图片

示例导出:

JAVA按模版导出PDF文件,含条码,二维码,表格_第2张图片

核心代码:

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: [email protected]
 * @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 textFields, Map barcodeFields, Map qrcodeFields,Map 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 fontList = new ArrayList();
		fontList.add(bf);

		AcroFields s = ps.getAcroFields();
		s.setSubstitutionFonts(fontList);
		
		//遍历表单字段
		for (Map.Entry 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 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 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 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> dataList = tableDto.getDataList();
				if(dataList != null && dataList.size() > 0){
					for(int i=0;i 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 textFields = new HashMap();
		textFields.put("ifCode", "ZC-TXJ-01");
		textFields.put("ifName", "获取单台或多台车实时位置及油耗数据");
		textFields.put("ifSource", "天行健");
		textFields.put("ifFrequency", "实时");
		textFields.put("ifType", "WebService");
		textFields.put("ifDesc", "当整车系统需要获取某台或多台车的实时位置时,即可实时调用此接口获取所查询车辆的坐标数据、油耗数据等");

		Map barcodeFields = new HashMap();
		barcodeFields.put("ifLogic", "12312312312");
		
		Map qrcodeFields = new HashMap();
		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> dataList = new ArrayList>();
		for(int i=0;i<15;i++){
			Map row = new HashMap();
			for(int j=1;j<5;j++){
				row.put("col"+j, "col"+j);
			}
			dataList.add(row);
		}
		tableDto.setDataList(dataList);
		Map tableFields = new HashMap();
		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 textFields = generator.getTextFields();
			Map barcodeFields = generator.getBarcodeFields();
			Map qrcodeFields = generator.getQrcodeFields();
			Map 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 textFields = new HashMap();
    private Map barcodeFields = new HashMap();
    private Map qrcodeFields = new HashMap();
    private Map tableFields = new HashMap();
    
    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 getTextFields() {
		return textFields;
	}
	public void setTextFields(Map textFields) {
		this.textFields = textFields;
	}
	public Map getBarcodeFields() {
		return barcodeFields;
	}
	public void setBarcodeFields(Map barcodeFields) {
		this.barcodeFields = barcodeFields;
	}
	public Map getQrcodeFields() {
		return qrcodeFields;
	}
	public void setQrcodeFields(Map qrcodeFields) {
		this.qrcodeFields = qrcodeFields;
	}
	public Map getTableFields() {
		return tableFields;
	}
	public void setTableFields(Map 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> 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> getDataList() {
		return dataList;
	}
	public void setDataList(List> dataList) {
		this.dataList = dataList;
	}
    
    
}

相关JAR包:


	com.itextpdf
	itextpdf
	5.5.10


	com.itextpdf
	itext-asian
	5.2.0

还是写点备注吧:

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

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

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

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

已上传实例

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

你可能感兴趣的:(JAVA,二维码,pdf,java)