最近做项目有个需求,在动态生成word文档的同时插入电子签名图片,这里使用freemarker来实现。
首先引入freemarker依赖:
org.freemarker
freemarker
2.3.28
首先模板要自己先画好,打开word自己制作一个模板:
然后将它另存为xml,修改相关内容后再另存为ftl文件,这样就可以使用了(抓取重要的几个部分)
//如果想要打出多个要是用list标签
<#list signs as sign>
....
//文字部分的替换
作战部队:${sign.army}
...
//图片部分(二维码也是一样的)
<#if (sign.signImage != "")>
${sign.signImage}
#if>
...
#list>
项目结构大致如下:
编写一个文件处理工具类:
@Component
public class DocumentUtil {
/**
* 生成word或excel文件
* @param dataMap word或excel中需要展示的动态数据,用map集合来保存
* @param templateName word或者excel模板名称,例如:test.ftl
* @param fileFullPath 要生成的文件全路径
*/
@SuppressWarnings("unchecked")
public static void createWordOrExcel(Map dataMap, String templateName, String fileFullPath) {
logger.info("[createWord]:==>方法进入");
logger.info("[fileFullPath]:==>" + fileFullPath);
logger.info("[templateName]:==>" + templateName);
try {
// 创建配置实例
Configuration configuration = new Configuration();
logger.info("[创建配置实例]:==>");
// 设置编码
configuration.setDefaultEncoding("UTF-8");
logger.info("[设置编码]:==>");
// 设置处理空值
configuration.setClassicCompatible(true);
// 设置ftl模板文件加载方式
configuration.setClassForTemplateLoading(DocumentUtil.class,"/template/ftl");
//创建文件
File file = new File(fileFullPath);
// 如果输出目标文件夹不存在,则创建
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
// 将模板和数据模型合并生成文件
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
// 获取模板
Template template = configuration.getTemplate(templateName);
// 生成文件
template.process(dataMap, out);
// 清空缓存
out.flush();
// 关闭流
out.close();
} catch (Exception e) {
logger.info("[生成word或excel文件出错]:==>" + e.getMessage());
e.printStackTrace();
}
}
}
二维码和图片的工具类:
public class QRCodeUtil {
/**
* 生成BASE64格式的二维码
* @param contents
* @param width
* @param height
* @return
*/
public static String creatRrCode(String contents, int width, int height) {
String binary = null;
Hashtable hints = new Hashtable();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
// 1、读取文件转换为字节数组
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedImage image = toBufferedImage(bitMatrix);
//转换成png格式的IO流
ImageIO.write(image, "png", out);
byte[] bytes = out.toByteArray();
// 2、将字节数组转为二进制
binary = new String(Base64.encodeBase64(bytes));
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return binary;
}
/**
* image流数据处理
*/
public static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
return image;
}
/**
* 根据图片url转成图片文件
* @param url
* @return
*/
public static File dealUrlToImage(String url) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
BufferedOutputStream stream = null;
InputStream inputStream = null;
File file = null;
try {
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
inputStream = conn.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
file = File.createTempFile("pattern", "." + "jpg");
FileOutputStream fileOutputStream = new FileOutputStream(file);
stream = new BufferedOutputStream(fileOutputStream);
stream.write(outStream.toByteArray());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (stream != null) {
stream.close();
}
outStream.close();
} catch (Exception e) {
}
return file;
}
}
public static String getImageStr(String imgFile){
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
}
controller
@Api(tags = "文件管理")
@RestController
@RequestMapping("/document")
public class FileController {
@ApiOperation(value="生成word文件测试")
@RequestMapping(value = "/createWord", method = RequestMethod.POST)
public String createWord() throws IOException {
Map resultMap = new HashMap<>();
List
如果你要生产成excel步骤也是和上面一样的