超详细---使用QRCode生成二维码并生成到PDF上

突发奇想想生成一个这样的一个带二维码的pdf:

超详细---使用QRCode生成二维码并生成到PDF上_第1张图片

然后就开始做了

废话不多说了直接上代码: 

POM.XML(所需要的jar)

里面的jar可能不全,根据错误提示需要自己再去引入jar



  
    org.apache.poi
    poi
    3.14
  

  
    org.apache.poi
    poi-ooxml
    3.14
  

  
    org.apache.poi
    poi-ooxml-schemas
    3.14
  

   
    org.apache.poi
    poi-scratchpad
    3.14
  


 
   org.apache.poi
   ooxml-schemas
   1.1
 

 
   org.apache.xmlbeans
   xmlbeans
   2.6.0
 


 
    org.apache.commons
    commons-pool2
    2.3
  


  
    com.itextpdf
    itextpdf
    5.5.12
  

  
    com.itextpdf
    itext-asian
    5.2.0
  

  
    com.itextpdf.tool
    xmlworker
    5.5.12
  









  fr.opensagres.xdocreport
  org.apache.poi.xwpf.converter.pdf 
  1.0.6



 
  fr.opensagres.xdocreport
  org.apache.poi.xwpf.converter.core
  1.0.6




  fr.opensagres.xdocreport
  fr.opensagres.xdocreport.document
  2.0.1





       
		
		
			com.google.zxing
			core
			3.0.0
		

        
           com.google.zxing
           javase
           3.3.1
        

 

工具类(Util)

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;

import org.apache.commons.codec.binary.Base64;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;


public final class QRCodeCreateUtil{
	
//	@Value("#{properties['contract.file.path']}")
//    protected static String CONTRACT_FILE_PATH; // 存放路径
    protected static String CONTRACT_FILE_PATH = "E:/MyQRCode"; // 存放路径

	private static final int BLACK = 0xff000000;
    private static final int WHITE = 0xFFFFFFFF;
	
    //创建文件夹
    public String getFtpPathFile() {
		String ftpPath = "";
		try {
			// 配置中配置
			File file = new File("这里写要创建的文件夹路径");
			// 如果文件夹不存在就新建一个文件夹
			if (!file.exists() && !file.isDirectory()) {
				boolean mkdir = file.mkdirs();
				if (mkdir = false) {
					return null;
				} else {
					ftpPath = file.getPath();
				}
				// 如果存在就取得本地址
			} else {
				ftpPath = file.getPath();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return ftpPath;
	}
    
	/**
     * 仅生成二维码,返回二维码图片网络地址,可直接扫码访问
     * @param contents:扫码地址
     * @return
     */
    public static String getQRCode(String contents){
    	String ftpPath = "";
        // 生成二维码的格式
    	String filePostfix="png";
        SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMDD");
        String today = sdf.format(new Date());//以日期分文件夹
        // 二维码图片名
        String fileName = UUID.randomUUID().toString().replaceAll("-", "")+ "." + filePostfix;
        //创建文件夹
        try {
			// 配置中配置
			File file = new File("D:\\Desktop\\Pdf\\OrCode\\");
			// 如果文件夹不存在就新建一个文件夹
			if (!file.exists() && !file.isDirectory()) {
				boolean mkdir = file.mkdirs();
				if (mkdir = false) {
					return null;
				} else {
					ftpPath = file.getPath();
				}
				// 如果存在就取得本地址
			} else {
				ftpPath = file.getPath();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
        
        // 保存文件的路径
        String fileUrl = ftpPath + today + fileName;
        
        File file = new File(fileUrl);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        
        // 生成QRCode二维码
        encode(contents, file, filePostfix, BarcodeFormat.QR_CODE, 500, 500, null);
        
        // 返回二维码地址
        return fileUrl;
    }
    
    /**
     *  生成QRCode二维码的数据流
* 在编码时需要将com.google.zxing.qrcode.encoder.Encoder.java中的
* static final String DEFAULT_BYTE_MODE_ENCODING = "ISO8859-1";
* 修改为UTF-8,否则中文编译后解析不了
* @param contents 二维码的内容 * @param file 二维码保存的路径,如:C://test_QR_CODE.png * @param filePostfix 生成二维码图片的格式:png,jpeg,gif等格式 * @param format qrcode码的生成格式 * @param width 图片宽度 * @param height 图片高度 * @param hints */ public static String encodeStream(String contents, BarcodeFormat format, int width, int height) { String base64Img = ""; try { BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, format, width, height); BufferedImage image = toBufferedImage(bitMatrix); ByteArrayOutputStream os=new ByteArrayOutputStream(); Base64 base64 = new Base64(); ImageIO.write(image, "png", os); base64Img = new String(base64.encode(os.toByteArray())); } catch (Exception e) { e.printStackTrace(); } return base64Img; } /** * 生成QRCode二维码
* 在编码时需要将com.google.zxing.qrcode.encoder.Encoder.java中的
* static final String DEFAULT_BYTE_MODE_ENCODING = "ISO8859-1";
* 修改为UTF-8,否则中文编译后解析不了
* @param contents 二维码的内容 * @param file 二维码保存的路径,如:C://test_QR_CODE.png * @param filePostfix 生成二维码图片的格式:png,jpeg,gif等格式 * @param format qrcode码的生成格式 * @param width 图片宽度 * @param height 图片高度 * @param hints */ public static void encode(String contents, File file, String filePostfix, BarcodeFormat format, int width, int height, Map hints) { try { BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, format, width, height); writeToFile(bitMatrix, filePostfix, file); } catch (Exception e) { e.printStackTrace(); } } /** * 生成二维码图片
* * @param matrix * @param format * 图片格式 * @param file * 生成二维码图片位置 * @throws IOException */ public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException { BufferedImage image = toBufferedImage(matrix); ImageIO.write(image, format, file); } /** * 生成二维码内容
* * @param matrix * @return */ public static BufferedImage toBufferedImage(BitMatrix matrix) { int width = matrix.getWidth(); int height = matrix.getHeight(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { image.setRGB(x, y, matrix.get(x, y) == true ? BLACK : WHITE); } } return image; } /** * 解析QRCode二维码 */ @SuppressWarnings("unchecked") public static String decode(String filePath) { String resultStr = ""; try { BufferedImage image; try { File imageFile = new File(filePath); image = ImageIO.read(imageFile); if (image == null) { System.out.println("Could not decode image"); } BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result; @SuppressWarnings("rawtypes") Hashtable hints = new Hashtable(); //解码设置编码方式为:utf-8 hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); result = new MultiFormatReader().decode(bitmap, hints); resultStr = result.getText(); System.out.println(resultStr); } catch (IOException ioe) { System.out.println("二维码解析失败"); // throw ioe; } catch (ReaderException re) { System.out.println("二维码解析失败"); // throw re; } } catch (Exception ex) { System.out.println("二维码解析失败"); // throw ex; } return resultStr; } }

FtpBaseManager(FileUtil)

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import javax.servlet.http.HttpServletResponse;

/**
 * 基础ftp manager类
 *
 */
public class FtpBaseManager{

	protected boolean uploadFileNative(String path, String filename, InputStream input) {
		boolean success = false;
		OutputStream os = null;
		String pic_path = null;
		try {

			// 获取Tomcat服务器所在的路径

			// 弃用(第一种做法)
			/* String tomcat_path = System.getProperty( "user.dir" ); */

			// (第二种做法)
			String tomcat_path = System.getProperty("catalina.home");

			// 获取Tomcat服务器所在路径的最后一个文件目录
			String bin_path = tomcat_path.substring(tomcat_path.lastIndexOf("\\") + 1, tomcat_path.length());
			// 若最后一个文件目录为bin目录,则服务器为手动启动
			if (("bin").equals(bin_path)) {// 手动启动Tomcat时获取路径为:D:\Software\Tomcat-8.5\bin
				// 获取保存上传图片的文件路径
				pic_path = tomcat_path.substring(0, System.getProperty("catalina.home").lastIndexOf("\\")) + "/webapps/"
						+ path;
			} else {// 服务中自启动Tomcat时获取路径为:D:\Software\Tomcat-8.5
				pic_path = tomcat_path + "/webapps/" + path;
			}

			// 弃用(规定路径)
			/* String pathAll = "D:\\testFile\\" + path; */
			/* String pathAll = path; */

			// 2、保存到临时文件
			// 1K的数据缓冲
			byte[] bs = new byte[1024];
			// 读取到的数据长度
			int len;
			// 输出的文件流保存到本地文件
			File tempFile = new File(pic_path);

			if (!tempFile.exists()) {
				tempFile.mkdirs();
			}
			os = new FileOutputStream(tempFile.getPath() + File.separator + filename);
			// 开始读取
			while ((len = input.read(bs)) != -1) {
				os.write(bs, 0, len);
			}
			success = true;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 完毕,关闭所有链接
			try {
				os.close();
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return success;

	}

	/**
	 * 数据流转byte
	 * 
	 * @param buf
	 * @return
	 */
	protected InputStream byte2Input(byte[] buf) {
		return new ByteArrayInputStream(buf);
	}

	/**
	 * byte转数据流
	 * 
	 * @param inStream
	 * @return
	 * @throws IOException
	 */
	protected byte[] input2byte(InputStream inStream) throws IOException {
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[100];
		int rc = 0;
		while ((rc = inStream.read(buff, 0, 100)) > 0) {
			swapStream.write(buff, 0, rc);
		}
		byte[] in2b = swapStream.toByteArray();
		return in2b;
	}

	protected byte[] getRemoteFile(String remoteUrl) {

		URL url;
		try {
			url = new URL(remoteUrl);

			URLConnection con = url.openConnection();
			InputStream in = con.getInputStream();
			ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
			byte[] buff = new byte[100];
			int rc = 0;
			while ((rc = in.read(buff, 0, 100)) > 0) {
				swapStream.write(buff, 0, rc);
			}
			byte[] in2b = swapStream.toByteArray();
			return in2b;
		} catch (Exception e) {
			return null;
		}
	}

	protected byte[] getRemoteFileNative(String path) {

		// path = path.replace("/", "//");
		File file = new File(path);
		InputStream in = null;
		try {
			in = new FileInputStream(file);
			ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
			byte[] buff = new byte[100];
			int rc = 0;
			while ((rc = in.read(buff, 0, 100)) > 0) {
				swapStream.write(buff, 0, rc);
			}
			in.close();
			byte[] in2b = swapStream.toByteArray();
			return in2b;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 找文件夹
	 * 
	 * @return
	 */
	protected String getFtpPath() {
		String ftpPath = "";
		try {
			// 配置中配置
			File file = new File("/lims/Desktop/Pdf");
			// 如果文件夹不存在就新建一个文件夹
			if (!file.exists() && !file.isDirectory()) {
				boolean mkdir = file.mkdirs();
				if (mkdir = false) {
					return null;
				} else {
					ftpPath = file.getPath();
				}
				// 如果存在就取得本地址
			} else {
				ftpPath = file.getPath();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return ftpPath;
	}

	/**
	 * 文件下载
	 * @param path
	 * @param response
	 * @return
	 */
	public HttpServletResponse download(String path, HttpServletResponse response) {
        try {
    		//读取文件相对路径
    	/*	String path = request.getParameter("path");
    		boolean  isFile = false;
    		if(path==""||path==null) return "";
    		String url = path;
    		if(!path.contains("/")){
    			return "";
    		}*/
    		/*String[] names = path.split("/");*/
    		// 获取文件名
    		/*String fileName = names[names.length-1];*/
        	
    		// 将文件路径放置File 文件流中
    		File file = new File(path);

    		String fileName = file.getName();
    		// 设置返回参数
    		response.setHeader("Pragma", "No-cache");
    		response.setHeader("Cache-Control", "no-cache");
    		response.setDateHeader("Expires", 0);
    		response.setHeader("X-Frame-Options", "ALLOW-FROM");
    		response.setHeader("Content-Disposition",
                    "attachment;filename=" + new String(fileName.getBytes(), "iso-8859-1"));
    		OutputStream output = response.getOutputStream();// 得到输出流
    		if(path.toLowerCase().endsWith(".pdf")){
    			response.setContentType("application/pdf");
    		}else {
    			return null;
    		}
    	
    		// 进行下载输出
    		InputStream imageIn = new FileInputStream(file);
    		BufferedInputStream bis = new BufferedInputStream(imageIn);// 输入缓冲流
    		BufferedOutputStream bos = new BufferedOutputStream(output);// 输出缓冲流
    		byte data[] = new byte[1024];// 缓冲字节数
    		int size = 0;
    		while ( ( size = bis.read(data) ) != -1) {
    			bos.write(data,0,size);
    		}
    		bis.close();
    		bos.flush();// 清空输出缓冲流
    		bos.close();
    		output.flush();
    		output.close();
    		return null;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return response;
    }

	
	
}

WordTemplateUtil (word模板处理工具类)

import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;


/**
 * word模板处理工具类
 */
public class WordTemplateUtil {

    /**
     * word文档转成PDF(适用于docx)
     * 
     * @param xwpfDocument docx文档对象
     * @param outputPath 生成文件路径
     * @return 生成文件绝对路径
     */
    public static String convertToPdf(XWPFDocument xwpfDocument, String outputPath, String fileName) {

        String resultFilePath = outputPath + "/" + fileName + ".pdf";

        PdfOptions pdfOptions = PdfOptions.create();
        try {
            PdfConverter.getInstance().convert(xwpfDocument, new FileOutputStream(resultFilePath),
                pdfOptions);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultFilePath;
    }

    /**
     * 解析Word替换文本(适用于doc)
     * 
     * @param hwpfDocument doc解析对象
     * @param paramMap 需要替换的信息集合
     */
    public static void replaceText(HWPFDocument hwpfDocument, Map paramMap) {

        // 获取段落
        Range range = hwpfDocument.getRange();

        for (Map.Entry entry : paramMap.entrySet()) {
            range.replaceText(entry.getKey(), entry.getValue());
        }
    }

    /**
     * 解析Word替换文本(适用于docx)
     * 
     * @param xwpfDocument docx解析对象
     * @param paramMap 需要替换的信息集合
     */
    public static void replaceText(XWPFDocument xwpfDocument, Map paramMap) {

        // 获取段落集合
        List paragraphs = xwpfDocument.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
            replaceRun(paragraph, paramMap);
        }
    }

    /**
     * 替换表格内的非动态内容(适用于docx)
     * 
     * @param document
     * @param paramMap
     */
    public static void replaceTableText(XWPFDocument document, Map paramMap) {

        //获取表格对象集合
        List tables = document.getTables();

        for (int t = 0; t < tables.size(); t++) {

            XWPFTable processTable = tables.get(t);
            if (processTable.getRows().size() > 0 && checkText(processTable.getText())) {

                List rows = processTable.getRows();

                for (int i = 0; i < rows.size(); i++) {
                    XWPFTableRow row = rows.get(i);

                    List cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        //判断单元格是否需要替换
                        if (checkText(cell.getText())) {
                            List paragraphs = cell.getParagraphs();
                            for (XWPFParagraph paragraph : paragraphs) {
                                replaceRun(paragraph, paramMap);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 替换表格对象方法(适用于docx)
     * @param document docx解析对象
     * @param dataList 需要插入的表格信息集合
     */
    public static void replaceTable(XWPFDocument document, List> dataList) {

        if (dataList == null || dataList.size() == 0) {
            return;
        }

        Map tempData = dataList.get(0);
        Set paramSet = tempData.keySet();

        //获取表格对象集合
        List tables = document.getTables();

        for (int t = 0; t < tables.size(); t++) {

            XWPFTable processTable = tables.get(t);
            if (processTable.getRows().size() > 1 && checkText(processTable.getText())
                && paramSet.contains(getFirstParam(processTable.getText()))) {
                // 模板行,用于复制
                XWPFTableRow templateRow = processTable.getRows().get(1);

                if (dataList == null || dataList.size() == 0) {
                    processTable.removeRow(1);
                    continue;
                }

                // 数据行数大于1,则添加总数减一行
                if (dataList != null && dataList.size() > 1) {
                    for (int i = 0; i < dataList.size() - 1; i++) {
                        XWPFTableRow insertRow = processTable.insertNewTableRow(2);
                        copyTableRow(templateRow, insertRow);
                    }
                }

                List rows = processTable.getRows();
                //遍历表格,并替换模板
                eachTable(rows, dataList);
            }
        }
    }

    /**
     * 遍历表格(适用于docx)
     * @param rows 表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(List rows, List> dataList) {

        for (int i = 0; i < dataList.size(); i++) {
            Map textMap = dataList.get(i);
            XWPFTableRow row = rows.get(i + 1);
            List cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                //判断单元格是否需要替换
                if (checkText(cell.getText())) {
                    List paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        replaceRun(paragraph, textMap);
                    }
                }
            }
        }
    }

    /**
     * 替换文字单元(适用于docx)
     * @param paragraph 文本段落
     * @param paramMap 参数集
     */
    private static void replaceRun(XWPFParagraph paragraph, Map paramMap) {

        String text = paragraph.getText();
        if (checkText(text)) {
            List runs = paragraph.getRuns();

            int start = -1;
            int end = -1;
            int startType = 0; // 1::以$开头, 2:以${开头,3:以${}结束
            for (int i = 0; i < runs.size(); i++) {
                XWPFRun run = runs.get(i);
                run.setFontFamily("宋体");//字体
                String runText = run.toString();
                // 对以${}括起来的字段进行替换
                if ('$' == runText.charAt(0)) {
                    start = i;

                    if (runText.length() > 1) {

                        if ('{' != runText.charAt(1)) {
                            start = -1; // 起始位置还原
                            continue;
                        } else {
                            startType = 2;
                        }
                    } else {
                        startType = 1;
                    }

                    if ('}' == runText.charAt(run.toString().length() - 1)) {
                        end = i;
                        startType = 3;
                    }
                }

                if (startType == 1 && start == i - 1 && runText.length() > 0 && '{' != runText.charAt(0)) {
                    start = -1; // 起始位置还原
                    continue;
                }

                if ((startType == 2 || startType == 1) && '}' == runText.charAt(run.toString().length() - 1)) {
                    end = i;
                }

                if (start != -1 && end != -1) { // 找到参数并替换

                    StringBuffer paramKey = new StringBuffer();
                    for (int j = start; j <= end; j++) {
                        run = runs.get(j);
                        paramKey.append(run.toString());
                    }

                    String mapKey = paramKey.toString();
                    mapKey = StringUtils.replace(mapKey, "${", "");
                    mapKey = StringUtils.replace(mapKey, "}", "");

                    for (int j = start; j <= end; j++) {
                        run = runs.get(j);
                        run.setText("", 0);
                    }

                    run = runs.get(start);
                    if (paramMap.containsKey(mapKey) && paramMap.get(mapKey) != null) {
                        run.setText(paramMap.get(mapKey), 0);
                    } else {
                        run.setText("", 0);
                    }

                    start = -1;
                    end = -1;
                }
            }
        }
    }

    /**
     * 判断文本中是否包含$
     * @param text 文本
     * @return 包含返回true,不包含返回false
     */
    private static boolean checkText(String text) {
        if (text.indexOf("$") != -1)
            return true;
        return false;
    }

    /**
     * 复制表格行(适用于docx)
     * @param sourceRow 原表格行
     * @param targetRow 目标行
     */
    private static void copyTableRow(XWPFTableRow sourceRow, XWPFTableRow targetRow) {
        //复制行属性
        targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
        List cellList = sourceRow.getTableCells();
        if (null == cellList) {
            return;
        }
        //添加列、复制列以及列中段落属性
        XWPFTableCell targetCell = null;
        for (XWPFTableCell sourceCell : cellList) {
            targetCell = targetRow.addNewTableCell();
            //列属性
            targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());

            XWPFParagraph targetCellParagraph = targetCell.getParagraphs().get(0);
            //段落属性
            targetCell.getParagraphs().get(0).getCTP()
                .setPPr(sourceCell.getParagraphs().get(0).getCTP().getPPr());

            // 复制文本单元
            for (XWPFRun sourceRun : sourceCell.getParagraphs().get(0).getRuns()) {
                XWPFRun targetRun = targetCellParagraph.createRun();
                targetRun.setText(sourceRun.toString());
            }
        }
    }

    /**
     * 截取第一个${}里面的参数
     * 
     * @param text
     * @return
     */
    private static String getFirstParam(String text) {

        String param = null;

        if (text != null) {
            int start = text.indexOf("${");
            int end = text.indexOf("}");
            try {
                if (start > 0 && start + 2 <= end) {
                    param = text.substring(start + 2, end);
                }
            } catch (Exception e) {
                return null;
            }
        }

        return param;
    }
}

ServiceImpl(二维码的逻辑处理)

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import PrincipalOrderManualDao;
import **.OrCodeDto;   //根据自己业务
import **.PrincipalOrderDataDto; //根据自己业务
import **.PrincipalOrder;  //根据自己业务
import **.SampleInfo;  //根据自己业务
import **.OrCodeManualService;  //根据自己业务
import 自己的路径.FtpBaseManager;
import 自己的路径.QRCodeCreateUtil;
import 自己的路径.WordTemplateUtil;

//日志(根据自己业务需要去加减--需要的话请引入jar包)
import fr.opensagres.xdocreport.core.logging.LogUtils;

@Service
public class OrCodeManualServiceImpl extends FtpBaseManager implements OrCodeManualService {

	@Autowired
	private PrincipalOrderManualDao principalOrderManualDao;

	/**
	 * 生成二维码
	 * 
	 * @param id
	 * @return
	 */
	public List str2codeBase(Long id) {
		List dtoList = new ArrayList();
		// 取得樣品明細
		PrincipalOrderDataDto sampleInfoById = principalOrderManualDao.getSampleInfoById(id);
		// 取得样品编码
		List sampleInfoList = sampleInfoById.getSampleInfoList();
		for (SampleInfo data : sampleInfoList) {
			OrCodeDto dto = new OrCodeDto();
			String contents = data.getSampleCode();
			// 开始生成二维码(生成的是一张图片)
			String qrCode = QRCodeCreateUtil.getQRCode(contents);
			dto.setOrCodeUrl(qrCode);
			dto.setOrcodeName(contents);
			dtoList.add(dto);
		}
		return dtoList;
	}

	/**
	 * 贴纸打印
	 * 
	 * @param id
	 *            委托订单id
	 * @param AbsolutePositionX
	 *            二维码位置X轴
	 * @param AbsolutePositionY
	 *            二维码位置X轴
	 * @param scalePercent
	 *            二维码缩放比例
	 * @return
	 */

	@Override
	/*
	 * public String doPut2CodeMark(Long id,float absolutePositionX, float
	 * absolutePositionY, float scalePercent) {
	 */
	public String doPut2CodeMark(Long id, HttpServletResponse response) {

		// 要加二维码的文件地址
		// 根据word生成新的pdf文件作为模板
		String url = pdfFileUrl(id);
		/* byte[] fileData = super.getRemoteFileNative(url); */
		InputStream input = null;
		try {
			input = new FileInputStream(new File(url));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		// 准备好要加二维码的文件
		String editFilePath = url;

		try {
			// 开始生成二维码(调用生成二维码的方法)
			List str2codeBase = str2codeBase(id);
			// 读取模板文件
			PdfReader reader = new PdfReader(input);
			PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(editFilePath));
			Document document = new Document(reader.getPageSize(1));
			// 获取页面宽度
			/*
			 * float absolutePositionNewX =
			 * document.getPageSize().getWidth()-300;
			 */
			// 获取页面高度
			float absolutePositionNewY = document.getPageSize().getHeight() - 150;
			// X轴位置的值
			float absolutePositionNewX = 80;
			
			//设置字体的位置
			
			// 获取页面高度
			float absolutePositionFontNewY = document.getPageSize().getHeight() - 160;
			// X轴位置的值
			float absolutePositionFontNewX = 75;
			
			// Y轴位置的值
			/* float absolutePositionNewY = 0; */
			// 图片缩放的比例值
			float scalePercent = 15;
			for (OrCodeDto imgBase64Code : str2codeBase) {
				// 提取pdf中的表单
				AcroFields form = stamper.getAcroFields();
				form.addSubstitutionFont(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED));
				// 取得二维码地址
				String orCodeUrl = imgBase64Code.getOrCodeUrl();
				// 取得二维码名称
				String orcodeName = imgBase64Code.getOrcodeName();
				// 根据地址读图片
				Image image = Image.getInstance(orCodeUrl); // 读取图片地址
				image.setAbsolutePosition(absolutePositionNewX, absolutePositionNewY);// 二维码的位置
				image.scalePercent(scalePercent); // 图片缩放的比例
				/*
				 * // 读取图片名称 PdfName role = image.getRole();
				 */
				int total = reader.getNumberOfPages();
				PdfContentByte content;

				content = stamper.getOverContent(total);
				// 开始写入文本
				content.beginText();
				//加字体
                                BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
                               //设置字体  参照: https://www.cnblogs.com/zwjbb1021/p/7844539.html
				Font font = new Font(bf, 10, Font.BOLD);
				// 设置字体和大小
				content.setFontAndSize(font.getBaseFont(), 10);
				// 设置字体的输出位置
				content.setTextMatrix(absolutePositionFontNewX, absolutePositionFontNewY);
				// 要输出的text  
				content.showText(orcodeName);
				
				content.endText();
				content.addImage(image);
				//字体换行
				if (absolutePositionFontNewX > 400.0) {
					// X轴从30开始
					absolutePositionFontNewX = 75;
					// Y轴换行
					absolutePositionFontNewY = absolutePositionFontNewY - 100;
				}else{
					// X轴换列
					absolutePositionFontNewX = absolutePositionFontNewX + 100;
				}
				
				//二维码换行
				if (absolutePositionNewX > 380.0) {
					// X轴从30开始
					absolutePositionNewX = 80;
					// Y轴换行
					absolutePositionNewY = absolutePositionNewY - 100;
				} else {
					// X轴换列
					absolutePositionNewX = absolutePositionNewX + 100;
				}
				/* content.setDefaultColorspace(role, orCodeUrl); */
				// 删除二维码
				File tempFile = new File(orCodeUrl);
				// 删除临时文件
				LogUtils.getLogger("删除临时");
				tempFile.delete();
				
			}
			stamper.close();
			reader.close();
			try {
				// 开始下载文件
				download(url, response);
				File tempFile = new File(url);
				// 删除临时文件
				LogUtils.getLogger("删除临时");
				tempFile.delete();
			} catch (Exception e) {
				LogUtils.getLogger("下载失败");
			}
			return url;
		} catch (Exception e) {
			LogUtils.getLogger(e.getMessage());
			e.printStackTrace();
			return "二维码生成失败!";
		}

	}

	// 根据模板生成一个新的pdf
	public String pdfFileUrl(Long id) {
		// 生成的PDF文件路径
		String pdfFilePath = null;
		// 取得委托单的基础信息
		PrincipalOrder principalOrder = principalOrderManualDao.getById(id);
		// 设置一个文件名
		String principalOrderName = principalOrder.getPrincipalOrderCode();
		// 模板路径
		String modelPath = "/static/pdf/QR_CODE.docx";
		/*String modelPath = "/lims/pdf/orcode.docx";*/
		/* String modelPath = "D:\\pdf\\moban\\QR_CODE.docx"; */
		// pdf生成后的名字
		String pdfPath = "PDF_" + principalOrderName;
		// 开始采集数据
		String principalOrder2 = getPrincipalOrder(id);
		// 根据模板开始生成pdf
		LogUtils.getLogger("根据模板生成PDF");
		pdfFilePath = generateContractChange(modelPath, pdfPath, principalOrder2);
		return pdfFilePath;
	}

	// 生成pdf
	private String generateContractChange(String filePath, String fileName, String sampleName) {
		String pdfFilePath = null;
		Map principalOrderMap = new HashMap();
		// 加标题
		/*principalOrderMap.put("name", "样品编码:" + sampleName);*/
		try {
			LogUtils.getLogger("开始读取文本文件流" + filePath);
			InputStream input = null;
			// 本地磁盘中
			/*File file = new File(filePath);
			input = new FileInputStream(file);*/
			// 项目中
			input = this.getClass().getResourceAsStream(filePath);
			// 读取模板
			LogUtils.getLogger("读取模板");
			XWPFDocument xwpfDocument = new XWPFDocument(input);
			// 替换文本
			LogUtils.getLogger("替换文本");
			WordTemplateUtil.replaceText(xwpfDocument, principalOrderMap);

			// 替换表格
			/*
			 * LogUtils.getLogger("替换表格");
			 * WordTemplateUtil.replaceTable(xwpfDocument, null);
			 */

			// 替换表格文本
			LogUtils.getLogger("替换表格文本");
			WordTemplateUtil.replaceTableText(xwpfDocument, principalOrderMap);

			// 生成好的pdf路径
			String pdfurl = getFtpPath();
			// 转成PDF
			LogUtils.getLogger("转换pdf");
			pdfFilePath = WordTemplateUtil.convertToPdf(xwpfDocument, pdfurl, fileName);
			input.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return pdfFilePath;
	}

	/**
	 * 取得样品编码数据
	 * 
	 * @param id
	 * @return
	 */
	public String getPrincipalOrder(Long id) {
		// 取得樣品明細
		PrincipalOrderDataDto sampleInfoById = principalOrderManualDao.getSampleInfoById(id);
		// 取得样品编码
		String contract = contract(sampleInfoById);
		return contract;

	}

	/**
	 * 处理样品编码(1,2,3的格式)
	 * 
	 * @param sampleInfoById
	 * @return
	 */
	public String contract(PrincipalOrderDataDto sampleInfoById) {
		List sampleInfoList = sampleInfoById.getSampleInfoList();
		List strList = new ArrayList();
		for (SampleInfo sampleInfo : sampleInfoList) {
			String sampleCode = sampleInfo.getSampleCode();
			strList.add(sampleCode);
		}
		String join = StringUtils.join(strList, ",");
		return join;
	}
}

你可能感兴趣的:(超详细---使用QRCode生成二维码并生成到PDF上)