需求
在服務(wù)端提前準備好Word模板文件,并在用戶請求接口時服務(wù)端動態(tài)獲取圖片。數(shù)據(jù)等信息插入到模板當(dāng)中,然后返回包含數(shù)據(jù)信息的Word文件流。
一、準備模板文件
在需要插入圖片的地方使用:{{@參數(shù)名}},文本信息使用:{{參數(shù)名}},進行占位,占位格式將會被保留,經(jīng)過處理后格式不變
將準備好的模板文件放在resources目錄下
二、引入Poi-tl、Apache POI依賴
poi-tl(poi template language)是Word模板引擎,基于Apache POI,提供更友好的API,使用起來更加簡單
版本對應(yīng)關(guān)系參考Poi-tl官網(wǎng)文章來源:http://www.zghlxwxcb.cn/news/detail-804316.html
<!-- 替換自己使用的版本 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.*</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.*</version>
</dependency>
<!-- Word模板引擎 -->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.7.*</version>
</dependency>
三、創(chuàng)建實體類(用于保存向Word中寫入的數(shù)據(jù))
參數(shù)名必須同Word模板中的參數(shù)名稱保持一致文章來源地址http://www.zghlxwxcb.cn/news/detail-804316.html
import com.deepoove.poi.data.PictureRenderData;
@Data
public class DownloadDate {
//圖片使用PictureRenderData類型
private PictureRenderData image;
private String name;
private String a;
private String b;
private String c;
private String d;
private String e;
private String f;
private String g;
private String h;
private String i;
}
四、實現(xiàn)Service接口
public interface DownloadService {
void download(HttpServletResponse response, DownloadDTO downloadDTO) throws IOException;
}
@Service
@Slf4j
public class DownloadServiceImpl implements DownloadService {
@Resource
//遠程調(diào)用服務(wù)
private FeignService feignService;
@Override
public void download(HttpServletResponse response, DownloadDTO downloadDTO) throws IOException {BufferedImage、字節(jié)數(shù)組),Base64可以轉(zhuǎn)字節(jié)數(shù)組后使用
//通過調(diào)用其它接口獲取待寫入的數(shù)據(jù)信息
WordData wordData = feignService.getData(downloadDTO);
/**
* 圖片可以是多種格式------------------------
* 圖片路徑:PictureRenderData(int width, int height, String path)
* File:PictureRenderData(int width, int height, File picture)
* InputStream:PictureRenderData(int width, int height, String format, InputStream input)
* BufferedImage:PictureRenderData(int width, int height, String format, BufferedImage image)
* 字節(jié)數(shù)組:PictureRenderData(int width, int height, String format, byte[] data)
* Base64可以轉(zhuǎn)字節(jié)數(shù)組后使用
*/
//以Base64為例,先獲取圖片的Base64編碼(wordData.getImg是原始圖片Base64數(shù)據(jù))
String base64ImageData = wordData.getImg.substring(data.indexOf(",") + 1);
//獲取圖片類型
String format = getBase64Type(base64ImageData);
// 將base64數(shù)據(jù)轉(zhuǎn)為字節(jié)數(shù)組
byte[] imageBytes = Base64.getDecoder().decode(base64ImageData);
// 將字節(jié)數(shù)組包裝成PictureRenderData
PictureRenderData pictureRenderData = new PictureRenderData(690,530,format,imageBytes);
//待寫入Word的數(shù)據(jù)
DownloadDate downloadDate = new DownloadDate();
//圖片信息
downloadDate.setImage(pictureRenderData);
//其它信息
downloadDate.setName(wordData.getName());
//...
XWPFTemplate template = null;
BufferedOutputStream bufferedOutputStream = null;
ServletOutputStream outputStream = null;
try {
/**
* 該方法會導(dǎo)致在部分環(huán)境中資源找不到的情況,不推薦使用
*/
//獲得resource路徑+模板路徑
//String path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath() + "word/template.docx";
// 讀取Word模板
//FileInputStream templateInputStream = new FileInputStream(path);
// 模板綁定數(shù)據(jù)
//template = XWPFTemplate.compile(templateInputStream).render(imageDownloadDate);
// 從資源中加載Word模板
try (InputStream templateInputStream = getClass().getClassLoader().getResourceAsStream("word/template.docx")) {
if (templateInputStream != null) {
// 模板綁定數(shù)據(jù)
template = XWPFTemplate.compile(templateInputStream).render(imageDownloadDate);
} else {
// 處理模板資源未找到的情況
log.error("Word模板資源未找到");
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
}
//文件名
String encodedFileName = URLEncoder.encode(System.currentTimeMillis()+"", "utf-8");
//設(shè)置響應(yīng)信息
response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName + ".docx");
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setCharacterEncoding("utf-8");
outputStream = response.getOutputStream();
bufferedOutputStream = new BufferedOutputStream(outputStream);
template.write(bufferedOutputStream);
//清空流
bufferedOutputStream.flush();
outputStream.flush();
} catch (Exception e) {
log.info(e.getMessage());
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
//關(guān)閉資源
PoitlIOUtils.closeQuietlyMulti(template, bufferedOutputStream, outputStream);
}
}
//根據(jù)base64編碼獲取圖片格式信息
private String getBase64Type(String base64) {
byte[] b = Base64.getDecoder().decode(base64);
String type = ".png";
if (0x424D == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
type = ".bmp";
} else if (0x8950 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
type = ".png";
} else if (0xFFD8 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
type = ".jpg";
} else if (0x49492A00 == ((b[0] & 0xff) << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff))) {
type = ".tif";
}
return type;
}
}
五、Controller層實現(xiàn)
@RestController
@RequestMapping("/test")
@Api(tags = "獲取商品圖片")
public class GetImageController {
@Resource
DownloadService downloadService;
@PostMapping("/download")
@ApiOperation(value = "下載Word")
void download(HttpServletResponse response,@RequestBody DownloadDTO downloadDTO) throws IOException {
//鑒權(quán)或其它處理
//....
downloadService.download(response,downloadDTO);
}
}
到了這里,關(guān)于JAVA實現(xiàn)向Word模板中插入Base64圖片和數(shù)據(jù)信息的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!