HZERO-报表解决中文乱码及字符缺失问题
1.前言HZERO的报表服务使用可以参考官方文档: http://hzerodoc.saas.hand-china.com/zh/docs/service/report/这里仅介绍中文乱码及字符缺失问题解决方案。官网提供了相关中文乱码解决方案但是实践证明,这种方式有个缺陷:①只能解决中文乱码问题,不能解决字符缺失问题。②需要下载字体放置到服务器。如果使用K8S部署,还要将字体路径映射到容器内部,繁
1.前言
HZERO的报表服务使用可以参考官方文档: http://hzerodoc.saas.hand-china.com/zh/docs/service/report/
这里仅介绍中文乱码及字符缺失问题解决方案。
官网提供了相关中文乱码解决方案
但是实践证明,这种方式有个缺陷:
①只能解决中文乱码问题,不能解决字符缺失问题。
②需要下载字体放置到服务器。如果使用K8S部署,还要将字体路径映射到容器内部,繁琐。
2.解决方案
1.思路
通过HZERO报表生成word,不会发生中文乱码及字符缺失问题。这种问题发生在报表PDF中。所以考虑先报表生成WORD,再将其通过aspose-words-15.8.0-jdk16.jar转换成PDF。这种放在使用window、linux、Mac
2.引入依赖
链接:http://pan.hand-china.com/owncloud/index.php/s/k9G9aLJlHFOgzF4
密码:123456
如图,将jar包放置在本地
引入依赖
<!--WORD转PDF-->
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/extraJar/aspose-words-15.8.0-jdk16.jar</systemPath>
</dependency>
3.开发
bjja.hzero.customs.api.controller.v1.PdfReportController
package bjja.hzero.customs.api.controller.v1;
import bjja.hzero.customs.app.service.PdfReportService;
import io.choerodon.core.iam.ResourceLevel;
import io.choerodon.swagger.annotation.Permission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
/**
* @author pgc
* @date 2020/6/9 17:17
*/
@Api(
tags = {"PDF REPORT"}
)
@Controller("pdfReportController.v1")
@RequestMapping({"/v1/{organizationId}/pdfReport"})
public class PdfReportController {
@Autowired
private PdfReportService pdfReportService;
@ApiOperation("导出新版PDF")
@Permission(
level = ResourceLevel.ORGANIZATION,
permissionLogin = true
)
@GetMapping({"/word2pdf/{reportUuid}/{outputType}"})
public void genPDFReport(
@PathVariable("reportUuid") String reportUuid,
@PathVariable("outputType") String outputType,
@RequestParam String fileName,
HttpServletRequest request,
HttpServletResponse response
) throws FileNotFoundException {
pdfReportService.genPDFReport(fileName, reportUuid, outputType, request, response);
}
}
bjja.hzero.customs.app.service.impl.PdfReportServiceImpl
package bjja.hzero.customs.app.service.impl;
import bjja.hzero.customs.app.service.PdfReportService;
import bjja.hzero.customs.feign.ReportRomoteService;
import bjja.hzero.customs.util.DownLoadUtil;
import bjja.sys.platform.customs.infra.mapper.HsCodeMapper;
import cn.pigicutils.core.convert.Convert;
import cn.pigicutils.core.exceptions.UtilException;
import cn.pigicutils.core.io.FileUtil;
import cn.pigicutils.core.io.IORuntimeException;
import cn.pigicutils.core.io.IoUtil;
import cn.pigicutils.core.lang.Assert;
import cn.pigicutils.core.util.StrUtil;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import lombok.SneakyThrows;
import org.hzero.core.base.BaseConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/**
* @author pgc
* @date 2020/6/9 17:25
*/
@Service
public class PdfReportServiceImpl implements PdfReportService {
@Autowired
private ReportRomoteService reportRomoteService;
@Autowired
private HsCodeMapper hsCodeMapper;
@Override
@SneakyThrows
public void genPDFReport(String fileName, String reportUuid, String outputType, HttpServletRequest request, HttpServletResponse response) {
String code = hsCodeMapper.selectCodeByReportId(reportUuid);
String headId = request.getParameter("headId");
DownLoadUtil.configDownload(response, StrUtil.concat(true, fileName, ".pdf"));
ServletOutputStream outputStream = response.getOutputStream();
Assert.notBlank(headId, "headId不能为空");
Long aLong = Convert.convert(Long.class, headId);
byte[] reportFile = reportRomoteService.getReportFile(BaseConstants.DEFAULT_TENANT_ID,
reportUuid,
outputType,
aLong,
code,
"zh_CN"
);
File fileParent = new File("/tmp");
if (!fileParent.exists()) {
fileParent.mkdirs();
}
File file = new File(fileParent, "/temp.docx");
if (file.exists()) {
file.delete();
}
File newfile = new File(fileParent, "/temp.docx");
File file1 = FileUtil.writeBytes(reportFile, newfile);
InputStream inputStream = new FileInputStream(file1);
try {
File file2 = genPDFwithWord(inputStream, "/tmp/tmp.pdf");
FileInputStream fileInputStream = new FileInputStream(file2);
try {
IoUtil.copy(fileInputStream, outputStream);
} catch (IORuntimeException e) {
e.printStackTrace();
} finally {
fileInputStream.close();
}
} catch (IORuntimeException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
inputStream.close();
}
}
/**
* WORD转PDF
*
* @param wordStream
* @param pdfPath
*/
@SneakyThrows
private File genPDFwithWord(InputStream wordStream, String pdfPath) {
// 验证License 若不验证则转化出的pdf文档会有水印产生
if (!getLicense()) {
throw new UtilException("证书校验不通过!");
}
// 新建一个空白pdf文档
File file = new File(pdfPath);
FileOutputStream os = new FileOutputStream(file);
// Address是将要被转化的word文档
Document doc = new Document(wordStream);
// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
doc.save(os, SaveFormat.PDF);
return file;
}
/**
* 获取证书,防止水印
*
* @return
*/
private boolean getLicense() {
boolean result = false;
try {
InputStream resourceAsStream = this.getClass().getResourceAsStream("/license.xml");
License aposeLic = new License();
aposeLic.setLicense(resourceAsStream);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
bjja.hzero.customs.util.DownLoadUtil
package bjja.hzero.customs.util;
import cn.pigicutils.core.exceptions.UtilException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* @Author: 潘顾昌
* @Date: 2019/9/24 11:26
*/
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class DownLoadUtil {
public static HttpServletResponse configDownload(HttpServletResponse response, String fileName) {
// 配置文件下载
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
// 下载文件能正常显示中文
try {
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new UtilException("转换出错!");
}
return response;
}
}
去除水印的license.xml下载,放在项目resources文件夹下
链接:http://pan.hand-china.com/owncloud/index.php/s/nwouW5UTiwdVwH5
密码:123456
更多推荐
所有评论(0)