突发奇想想生成一个这样的一个带二维码的pdf:
然后就开始做了
废话不多说了直接上代码:
POM.XML(所需要的jar)
里面的jar可能不全,根据错误提示需要自己再去引入jar
<!-- PDF相关 start -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.12</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.12</version>
</dependency>
<!--https://mvnrepository.com/artifact/fr.opensagres.xdocreport/org.apache.poi.xwpf.converter.xhtml -->
<!-- <dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
<version>1.0.6</version>
</dependency>
-->
<!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/org.apache.poi.xwpf.converter.pdf -->
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
<version>1.0.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/org.apache.poi.xwpf.converter.core -->
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>org.apache.poi.xwpf.converter.core</artifactId>
<version>1.0.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.xdocreport.document -->
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.document</artifactId>
<version>2.0.1</version>
</dependency>
<!-- PDF相关 end -->
<!--二维码-->
<!--<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency> -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.1</version>
</dependency>
工具类(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二维码的数据流<br>
* 在编码时需要将com.google.zxing.qrcode.encoder.Encoder.java中的<br>
* static final String DEFAULT_BYTE_MODE_ENCODING = "ISO8859-1";<br>
* 修改为UTF-8,否则中文编译后解析不了<br>
* @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二维码<br>
* 在编码时需要将com.google.zxing.qrcode.encoder.Encoder.java中的<br>
* static final String DEFAULT_BYTE_MODE_ENCODING = "ISO8859-1";<br>
* 修改为UTF-8,否则中文编译后解析不了<br>
* @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<EncodeHintType, ?> hints) {
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, format, width, height);
writeToFile(bitMatrix, filePostfix, file);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 生成二维码图片<br>
*
* @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);
}
/**
* 生成二维码内容<br>
*
* @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<String, String> paramMap) {
// 获取段落
Range range = hwpfDocument.getRange();
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
range.replaceText(entry.getKey(), entry.getValue());
}
}
/**
* 解析Word替换文本(适用于docx)
*
* @param xwpfDocument docx解析对象
* @param paramMap 需要替换的信息集合
*/
public static void replaceText(XWPFDocument xwpfDocument, Map<String, String> paramMap) {
// 获取段落集合
List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
replaceRun(paragraph, paramMap);
}
}
/**
* 替换表格内的非动态内容(适用于docx)
*
* @param document
* @param paramMap
*/
public static void replaceTableText(XWPFDocument document, Map<String, String> paramMap) {
//获取表格对象集合
List<XWPFTable> 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<XWPFTableRow> rows = processTable.getRows();
for (int i = 0; i < rows.size(); i++) {
XWPFTableRow row = rows.get(i);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
//判断单元格是否需要替换
if (checkText(cell.getText())) {
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
replaceRun(paragraph, paramMap);
}
}
}
}
}
}
}
/**
* 替换表格对象方法(适用于docx)
* @param document docx解析对象
* @param dataList 需要插入的表格信息集合
*/
public static void replaceTable(XWPFDocument document, List<Map<String, String>> dataList) {
if (dataList == null || dataList.size() == 0) {
return;
}
Map<String, String> tempData = dataList.get(0);
Set<String> paramSet = tempData.keySet();
//获取表格对象集合
List<XWPFTable> 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<XWPFTableRow> rows = processTable.getRows();
//遍历表格,并替换模板
eachTable(rows, dataList);
}
}
}
/**
* 遍历表格(适用于docx)
* @param rows 表格行对象
* @param textMap 需要替换的信息集合
*/
public static void eachTable(List<XWPFTableRow> rows, List<Map<String, String>> dataList) {
for (int i = 0; i < dataList.size(); i++) {
Map<String, String> textMap = dataList.get(i);
XWPFTableRow row = rows.get(i + 1);
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
//判断单元格是否需要替换
if (checkText(cell.getText())) {
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
replaceRun(paragraph, textMap);
}
}
}
}
}
/**
* 替换文字单元(适用于docx)
* @param paragraph 文本段落
* @param paramMap 参数集
*/
private static void replaceRun(XWPFParagraph paragraph, Map<String, String> paramMap) {
String text = paragraph.getText();
if (checkText(text)) {
List<XWPFRun> 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<XWPFTableCell> 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<OrCodeDto> str2codeBase(Long id) {
List<OrCodeDto> dtoList = new ArrayList<OrCodeDto>();
// 取得樣品明細
PrincipalOrderDataDto sampleInfoById = principalOrderManualDao.getSampleInfoById(id);
// 取得样品编码
List<SampleInfo> 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<OrCodeDto> 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<String, String> principalOrderMap = new HashMap<String, String>();
// 加标题
/*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<SampleInfo> sampleInfoList = sampleInfoById.getSampleInfoList();
List<String> strList = new ArrayList<String>();
for (SampleInfo sampleInfo : sampleInfoList) {
String sampleCode = sampleInfo.getSampleCode();
strList.add(sampleCode);
}
String join = StringUtils.join(strList, ",");
return join;
}
}