记录富文本内容生成word并在线预览碰到的问题,以及最终的解决方案。
一、需求
当前项目需要将页面富文本中的内容,生成word并在线预览。
二、解决方案1(未解决)
1. openoffice word在线预览
首先我先解决的是word的在线预览问题。这个用的是通用的方案,在电脑上安装openoffice插件,启动插件,然后是代码中调用暴露的API,然后实现word的在线预览。
2. 将富文本的html内容生成word
通过调用三方API,将富文本中的html内容生成word文件,然后再去预览。
问题:在通过将html装成word文件之后,openoffice插件却无法正常预览。通过看了下生成的word文件和正常创建的word文件对比,发现html生成的world,只是将html包裹了一层,和正常生成的word不一样。由此推测可能是该问题导致无法预览。
三、解决方案2(已解决)
在遇到方案2的问题时,发现暂时没有办法解决,因此换了一种方式。
1.将富文本的html内容生成word
和之前一样,先通过富文本保存的html内容,生成word。
2.将富文本的html内容生成PDF
这个多加了一步,通过富文本宝成的html内容,生成对应的PDF。
3.通过PDF进行预览。
通过接口,将PDF进行对外在线预览,如有需要将word发送给别人。
优点:不需要再安装openoffice插件,也不用启动openoffice。可直接进行预览。
缺点:需要同时生成PDF,当word有变动时,需要重新生成PDF。
四、源码
1.maven 依赖
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-export-fo</artifactId>
<version>6.1.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.8</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
2. 生成word、pdf
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import org.springframework.util.StringUtils;
import java.io.*;
import java.nio.charset.Charset;
public class OfficeUtil {
/**
* 通过html生成PDF
*
* @param htmlContent html格式内容
* @param file 输出文件file
*/
public static void createdPdfByItextHtml(String htmlContent, File file) {
InputStream inputStream = null;
FileOutputStream outputStream = null;
PdfWriter writer = null;
try {
// 1. 获取生成pdf的html内容
inputStream = new ByteArrayInputStream(htmlContent.getBytes("utf-8"));
outputStream = new FileOutputStream(file);
Document document = new Document();
writer = PdfWriter.getInstance(document, outputStream);
document.open();
// 2. 添加字体
// XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
// fontImp.register(getFontPath());
// 3. 设置编码
XMLWorkerHelper.getInstance().parseXHtml(writer, document, inputStream, Charset.forName("UTF-8"), new CustomXMLWorkerFontProvider());
// 4. 关闭,(不关闭则会生成无效pdf)
document.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
if (outputStream != null) {
outputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
/**
* 通过HTML生成Word
*
* @param htmlbody
* @param fileName
* @return
* @throws Exception
*/
public static File createWordByHtml(String htmlbody, String fileName) throws Exception {
File file = new File(fileName);
OutputStream outputStream = new FileOutputStream(file);
outputStream.write(htmlbody.getBytes());
outputStream.flush();
outputStream.close();
return file;
}
public static void createDir(String dirPath) {
File file = new File(dirPath);
if (!file.exists()) {
file.mkdirs();
}
}
public static String generateHtmlBody(String detailContent) {
detailContent = StringUtils.isEmpty(detailContent) ? "<h1 style=\"margin-left:28px\"><strong><span style=\";font-family:宋体;font-size:29px\">当前无展示内容</span></strong></h1>" : detailContent;
String html = "<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
"\t<title></title>\n" +
"</head>\n" +
"<body>\n" +
detailContent +
"</body>\n" +
"</html>";
return html;
}
}
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
/**
* 解决XMLWorkerHelper中文不显示。
* <p>使用iTextAsian.jar中自带的中文字体
*/
public class CustomXMLWorkerFontProvider extends XMLWorkerFontProvider {
@Override
public Font getFont(final String fontName, final String encoding, final boolean embedded, final float size, final int style,
final BaseColor color) {
BaseFont bf = null;
try {
bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
Font font = new Font(bf, size, style, color);
font.setColor(color);
// log.info("PDF文档字体初始化完成!");
return font;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
3.预览
public void preview(HttpServletResponse response) {
byte[] data = null;
FileInputStream input = new FileInputStream(new File("文件路径"));
data = new byte[input.available()];
input.read(data);
response.getOutputStream().write(data);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}