对称加密算法AES
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class AESUtils {
public static final int KEY_SIZE = 128;
private static final String AES_ALGORITHM = "AES";
private static final String PRNG_ALGORITHM = "SHA1PRNG";
public static String encrypt(String plainText, String rule) {
try {
Key key = generateKey(rule);
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] data = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return base64Encode(Hex.encodeHexString(data).getBytes(StandardCharsets.UTF_8));
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
return null;
}
public static String decrypt(String cipherText, String rule) {
try {
byte[] bytes = Hex.decodeHex(new String(base64Decode(cipherText), StandardCharsets.UTF_8).toCharArray());
Key key = generateKey(rule);
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] data = cipher.doFinal(bytes);
return new String(data, StandardCharsets.UTF_8);
} catch (DecoderException | GeneralSecurityException e) {
e.printStackTrace();
}
return null;
}
private static Key generateKey(String key) {
try {
SecureRandom secureRandom = SecureRandom.getInstance(PRNG_ALGORITHM);
secureRandom.setSeed(key.getBytes(StandardCharsets.UTF_8));
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM);
keyGenerator.init(KEY_SIZE, secureRandom);
return new SecretKeySpec(keyGenerator.generateKey().getEncoded(), AES_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public static String base64Encode(byte[] data) {
return Base64.encodeBase64String(data);
}
public static byte[] base64Decode(final String base64String) {
return StringUtils.isEmpty(base64String) ? null : Base64.decodeBase64(base64String);
}
public static void main(String[] args) {
String plainText = "中国abc123";
String rule = "123中国";
String encrypt = encrypt(plainText, rule);
System.out.println(encrypt);
String decrypt = decrypt(encrypt, rule);
System.out.println(decrypt);
System.out.println(plainText.substring(0, 0));
}
}
字符串转义
public class StringUtils {
private static final String[] regExpMetaElement = {"$", "(", ")", "*", "+", ".", "[", "]", "?", "\\", "^", "{", "}", "|"};
public static String escapeRegExpString(String plainText) {
if (org.apache.commons.lang3.StringUtils.isNotEmpty(plainText)) {
for (String element : regExpMetaElement) {
if (plainText.contains(element)) {
return plainText.replace(element, "\\" + element);
}
}
}
return plainText;
}
}
PDF转图片
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.util.Assert;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ImageConverterUtils {
private static final String DEFAULT_IMG_EXTENSION = FileConstants.EXTENSION_JPG;
public static List<String> convert(String originalFile, String imgExtension, float imgScale) {
Assert.notNull(originalFile, "original file must not be null");
File srcFile = new File(originalFile);
if (!srcFile.exists() || !srcFile.isFile()) {
throw new RuntimeException("original file not exist");
}
if (StringUtils.isEmpty(imgExtension)) {
imgExtension = DEFAULT_IMG_EXTENSION;
}
List<String> imgList = new ArrayList<>();
try (PDDocument document = PDDocument.load(srcFile);) {
int pages = document.getNumberOfPages();
PDFRenderer renderer = new PDFRenderer(document);
for (int i = 0; i < pages; i++) {
BufferedImage image = renderer.renderImage(i, imgScale, ImageType.RGB);
String imgPath = FilenameUtils.getFilenameWithoutExt(originalFile) + "_" + i + imgExtension;
ImageIO.write(image, imgExtension.substring(1), new File(imgPath));
imgList.add(imgPath);
}
} catch (IOException e) {
e.printStackTrace();
}
return imgList;
}
}
文件用到的常量
public interface FileConstants {
String EXTENSION_DOCX = ".docx";
String EXTENSION_DOC = ".doc";
String EXTENSION_PDF = ".pdf";
String EXTENSION_PNG = ".png";
String EXTENSION_JPG = ".jpg";
String EXTENSION_JPEG = ".jpeg";
String EXTENSION_GIF = ".gif";
String EXTENSION_BMP = ".bmp";
String EXTENSION_WEBP = ".webp";
String UPLOAD_PATH = "/upload";
String TMP_UPLOAD_PATH = "/upload/tmp";
String DEFAULT_DOWNLOAD_CONTENT_TYPE = "application/octet-stream";
String DOWNLOAD_CONTENT_DISPOSITION = "Content-Disposition";
String DOWNLOAD_CONTENT_DISPOSITION_PREFIX = "attachment;filename=";
}
文件名工具类
import org.springframework.util.Assert;
import java.nio.charset.StandardCharsets;
public class FilenameUtils {
public static boolean isTypeForMSWord(String filename) {
Assert.notNull(filename, "file name must not be null");
String[] p = filename.split(StringUtils.escapeRegExpString("."));
if (p.length > 0) {
return filename.endsWith(FileConstants.EXTENSION_DOCX) || filename.endsWith(FileConstants.EXTENSION_DOC);
} else {
throw new RuntimeException("file name isn't valid");
}
}
public static String getFilenameForPDF(String filename) {
String filenameWithoutExt = getFilenameWithoutExt(filename);
//.文件
if (filename.equals(filenameWithoutExt)) {
throw new RuntimeException("directory can't transform to the same file name with .pdf");
}
return filenameWithoutExt + FileConstants.EXTENSION_PDF;
}
public static String getFilenameWithoutExt(String filename) {
Assert.notNull(filename, "file name must not be null");
int index = filename.lastIndexOf(".");
if (index != -1) {
return filename.substring(0, index);
}
return filename;
}
}
转PDF服务
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.util.ArrayList;
import java.util.List;
/**
* support convert word to PDF in Linux,
* do nothing if Windows
*/
public class PDFConverterUtils {
public static void convert(String officeHome, String originalFile, String targetFile) {
Assert.notNull(originalFile, "original file must not be null");
File srcFile = new File(originalFile);
if (!srcFile.exists() || !srcFile.isFile()) {
throw new RuntimeException("original file not exist");
}
if (SystemUtils.IS_OS_LINUX) {
// kill process
String cmd = "ps -ef | grep " + officeHome + " | grep -v grep | awk '{print $2}' | xargs kill -9";
CommandLine commandLine = CommandLine.parse(cmd);
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(0);
try {
executor.execute(commandLine);
} catch (IOException e) {
e.printStackTrace();
}
}
String outDir = srcFile.getParent();
List<String> sh = new ArrayList<>();
sh.add(officeHome);
sh.add(" --headless --invisible --convert-to pdf:writer_pdf_Export ");
sh.add(originalFile);
sh.add(" --outdir ");
sh.add(outDir);
CommandLine commandLine = CommandLine.parse(String.join("", sh));
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(0);
try {
executor.execute(commandLine);
} catch (IOException e) {
e.printStackTrace();
}
File tmpFile = new File(FilenameUtils.getFilenameForPDF(originalFile));
if (tmpFile.exists() && tmpFile.isFile()) {
if (StringUtils.isNotEmpty(targetFile)) {
try (InputStream in = new BufferedInputStream(new FileInputStream(tmpFile));
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(targetFile)))) {
FileCopyUtils.copy(in, out);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
word模板填充
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.usermodel.PositionInParagraph;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
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.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WordConverterUtils {
/**
* 占位符正则表达式
*/
private static final Pattern REGEXP_PLACEHOLDER = Pattern.compile("\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
public static void convert(String originalFile, String targetFile, Map<String, String> data) {
boolean isTypeForMSWord = FileUtils.isTypeForMSWord(originalFile);
if (!isTypeForMSWord) {
throw new RuntimeException("unsupported file type");
}
File srcFile = new File(originalFile);
if (!srcFile.exists() || !srcFile.isFile()) {
throw new RuntimeException("转换文件不存在");
}
File destFile = new File(targetFile);
if (!destFile.exists() || !destFile.isFile()) {
try {
destFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
data = convertNull(data);
if (originalFile.endsWith(FileConstants.EXTENSION_DOCX)) {
handleWithDocxFormatted(originalFile, targetFile, data);
}
if (originalFile.endsWith(FileConstants.EXTENSION_DOC)) {
handleWithDocFormatted(originalFile, targetFile, data);
}
}
private static Map<String, String> convertNull(Map<String, String> data) {
for (Map.Entry<String, String> entry : data.entrySet()) {
if (entry.getValue() == null) {
data.put(entry.getKey(), "");
}
}
return data;
}
private static void handleWithDocFormatted(final String docPath, final String newDocPath, Map<String, String> data) {
try (InputStream in = new FileInputStream(docPath);
OutputStream out = new FileOutputStream(newDocPath)) {
HWPFDocument document = new HWPFDocument(in);
// 读取word文本内容
Range range = document.getRange();
for (Map.Entry<String, String> entry : data.entrySet()) {
String fullPlaceholder = "{" + entry.getKey() + "}";
range.replaceText(fullPlaceholder, entry.getValue());
}
document.write(out);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void handleWithDocxFormatted(final String docxPath, final String newDocxPath, Map<String, String> data) {
try (InputStream in = new FileInputStream(docxPath);
OutputStream out = new FileOutputStream(newDocxPath)) {
XWPFDocument document = new XWPFDocument(in);
Iterator<XWPFParagraph> paragraphsIterator = document.getParagraphsIterator();
while (paragraphsIterator.hasNext()) {
replaceTextInParagraph(paragraphsIterator.next(), data);
}
document.write(out);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void replaceTextInParagraph(XWPFParagraph paragraph, Map<String, String> data) {
List<XWPFRun> runs = paragraph.getRuns();
Matcher matcher = REGEXP_PLACEHOLDER.matcher(paragraph.getParagraphText());
if (matcher.find()) {
CTRPr ctrPr = getFirstRunStyleOfParagraph(paragraph);
int beginRunIndex = paragraph.searchText("{", new PositionInParagraph()).getBeginRun();
int endRunIndex = paragraph.searchText("}", new PositionInParagraph()).getEndRun();
StringBuilder key = new StringBuilder();
if (beginRunIndex == endRunIndex) {
// {***}在一个Run标签内
XWPFRun beginRun = runs.get(beginRunIndex);
String beginRunText = beginRun.toString();
int beginIndex = beginRunText.indexOf("{");
int endIndex = beginRunText.indexOf("}");
int length = beginRunText.length();
XWPFRun insertNewRun = paragraph.insertNewRun(beginRunIndex);
setFontStyle(ctrPr, insertNewRun);
key.append(beginRunText.substring(beginIndex + 1, endIndex));
if (beginIndex == 0 && endIndex == length - 1) {
// 该Run内只有{***}
String textString = data.get(key.toString());
System.out.println(key);
System.out.println(textString);
insertNewRun.setText(textString);
} else {
// 该Run内***{***}***
String textString = beginRunText.substring(0, beginIndex) + data.get(key.toString()) + beginRunText.substring(endIndex + 1);
insertNewRun.setText(textString);
}
paragraph.removeRun(beginRunIndex + 1);
} else {
// {***}被分成多个Run
// 获取beginRun中的key值
XWPFRun beginRun = runs.get(beginRunIndex);
String beginRunText = beginRun.toString();
int beginIndex = beginRunText.indexOf("{");
if (beginRunText.length() > 1) {
key.append(beginRunText.substring(beginIndex + 1));
}
// 获取中间Run的key值,也是需要移除的Run
List<Integer> removeRunList = new ArrayList<>();
for (int i = beginRunIndex + 1; i < endRunIndex; i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
key.append(runText);
removeRunList.add(i);
}
// 获取endRun中的key值
XWPFRun endRun = runs.get(endRunIndex);
String endRunText = endRun.toString();
int endIndex = endRunText.indexOf("}");
if (endRunText.length() > 1 && endIndex != 0) {
// Run中***}或者***}***
key.append(endRunText.substring(0, endIndex));
}
// 获取到完整key后进行替换
// 先处理开始标签
if (beginRunText.length() == 1) {
// Run标签内只有{
XWPFRun insertNewRun = paragraph.insertNewRun(beginRunIndex);
setFontStyle(ctrPr, insertNewRun);
insertNewRun.setText(data.get(key.toString()));
ctrPr = getFirstRunStyleOfParagraph(paragraph);
paragraph.removeRun(beginRunIndex + 1);
} else {
// Run标签为***{***或者{***
// 此时替换时须加上原key前文本
XWPFRun insertNewRun = paragraph.insertNewRun(beginRunIndex);
setFontStyle(ctrPr, insertNewRun);
String textString = beginRunText.substring(0, beginIndex) + data.get(key.toString());
insertNewRun.setText(textString);
paragraph.removeRun(beginRunIndex + 1);
}
// 处理结束标签
if (endRunText.length() == 1) {
// Run标签内只有}
XWPFRun insertNewRun = paragraph.insertNewRun(endRunIndex);
setFontStyle(ctrPr, insertNewRun);
insertNewRun.setText("");
paragraph.removeRun(endRunIndex + 1);
} else {
// Run标签为***}***或者***}
// 此时替换时须加上原key后文本
XWPFRun insertNewRun = paragraph.insertNewRun(endRunIndex);
setFontStyle(ctrPr, insertNewRun);
String textString = endRunText.substring(endIndex + 1);
insertNewRun.setText(textString);
paragraph.removeRun(endRunIndex + 1);
}
// 删除中间Run
for (int j = 0; j < removeRunList.size(); j++) {
XWPFRun insertNewRun = paragraph.insertNewRun(removeRunList.get(j));
setFontStyle(ctrPr, insertNewRun);
insertNewRun.setText("");
paragraph.removeRun(removeRunList.get(j) + 1);
}
}
replaceTextInParagraph(paragraph, data);
}
}
private static CTRPr getFirstRunStyleOfParagraph(XWPFParagraph paragraph) {
if (paragraph != null) {
List<XWPFRun> runs = paragraph.getRuns();
if (runs != null && runs.size() > 0) {
XWPFRun firstRun = runs.get(0);
return firstRun.getCTR().getRPr();
}
}
return null;
}
private static void setFontStyle(CTRPr ctrPr, XWPFRun xwpfRun) {
if (ctrPr != null) {
xwpfRun.getCTR().setRPr(ctrPr);
}
}
}