背景

之前有的教辅标注需求,在导出题库的时候希望顺便导出可以查看word,方便线下预览成品效果,因为只是用来预览并且为了沿用前端的样式,当时方案就是直接生成html,写个word的文件头,这样就可以用word打开查看了,文件头如下:

<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
</html>

直接在html里面填充内容即可,将后缀一改,word(伪)就生成了,但是这样的word有个致命的缺陷(客户机器必须联网,否则wor当中图片无法加载),并且随着业务的发展,导出的word客户想再次导入系统,这种html格式无法正常识别。需要导出标准格式的word并且顺便提了个需求,希望标注中latex公式在word中可以编辑

常见的word导出方案

  • Apache POI
  • FreeMark模板引擎生成xml格式文档
  • Aspose word(商业付费)
  • Spire.Doc(有商业版也有免费版)

其中Aspose word是不支持Latex公式的;使用Apache POI基本上是把Latex转成mathMl然后再写入到word中去,需要用到fmath两个jar包,在网上找了一些,没有找到正规取到,先pass;FreeMark写入其实也用到了fmath,需要将latex转成mathml格式,再写入到word的xml模板中,不过二次加工调用的引擎不支持xml编码的格式的word,所以此方案也pass

使用Spire.Doc导出支持编辑latex公式的word

依赖

<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc.free</artifactId>
<version>3.9.0</version>
</dependency>

创建Document对象和Section

Document document = new Document();
Section section = document.addSection();

创建段落,设置前后边距

Paragraph paragraph = section.addParagraph();
paragraph.getFormat().setLineSpacing(15);
paragraph.getFormat().setBeforeSpacing(20);

写入文字及设置中英文字体

TextRange textRange = paragraph.appendText(text);
textRange.getCharacterFormat().setFontNameFarEast("宋体");
textRange.getCharacterFormat().setFontNameNonFarEast("Times New Roman");

写入latex公式

OfficeMath math = new OfficeMath(paragraph.getDocument());
paragraph.getItems().add(math);
math.fromLatexMathCode(latexFormat(innerPojo.latex)); /**
* 这里spire.doc有一些缺陷,对于一些符号支持的不是很好,大于等于小于等于,这里做一下替换,连续中文也做了\mbox{}包裹,这个是基于latex的经验,但是实际并没有什么用,spire.doc不支持带有中文的latex公式渲染,可能版本太低了,所以不能正常渲染就直接显示图片
*/
private String latexFormat(String latex) {
if (latex.contains("leqslant")) {
latex = latex.replace("leqslant", "leq");
}
if (latex.contains("geqslant")) {
latex = latex.replace("geqslant", "geq");
}
StringBuilder latexBuilder = new StringBuilder();
boolean isChinese = false;
String regexStr = "[\u4E00-\u9FA5]";
for (Character c : latex.toCharArray()) {
Matcher chineseMatch = Pattern.compile(regexStr).matcher(c.toString());
if (chineseMatch.find()) {
if (isChinese) {
latexBuilder.append(c);
} else {
latexBuilder.append("\\mbox{").append(c);
isChinese = true;
}
continue;
} else {
if (isChinese) {
isChinese = false;
latexBuilder.append("}");
}
latexBuilder.append(c);
}
}
return latexBuilder.toString();
}

绘制表格

spire.doc中api中无法直接再段落中直接添加表格,需要先添加一个文本框,然后在文本框的内部再添加表格,这里事先把表格的二维数组绘制好

TextBox textBox = paragraph.appendTextBox(500, 20 * innerPojo.rows);
textBox.getFormat().setHorizontalAlignment(ShapeHorizontalAlignment.Inside);
textBox.getFormat().setNoLine(true);
Table table = textBox.getBody().addTable(true);
table.resetCells(innerPojo.rows, innerPojo.lines);
for (int i = 0; i < innerPojo.rowLines.size(); i++) {
List<String> rowLine = innerPojo.rowLines.get(i);
for (int j = 0; j < rowLine.size(); j++) {
appendWithFont(rowLine.get(j), table.get(i, j).addParagraph());
}
}
// 设置文本框样式嵌入型
textBox.setTextWrappingStyle(TextWrappingStyle.Inline);

这个版本的api找了一下,没有发现可以让文本框的高度自适应的方法,或许收费版本会好很多

插入图片

控制一下图片宽度不要超过500,高度不要超过300

DocPicture picture = paragraph.appendPicture(innerPojo.getImage());
log.info("pictureSize,Width:{},Height:{}", picture.getWidth(), picture.getHeight());
if (picture.getWidth() > 500) {
BigDecimal rate = BigDecimal.valueOf(500).divide(BigDecimal.valueOf(picture.getWidth()), 8, BigDecimal.ROUND_DOWN);
picture.setHeight(picture.getHeight() * rate.floatValue());
picture.setWidth(500);
} else if (picture.getHeight() > 300) {
BigDecimal rate = BigDecimal.valueOf(300).divide(BigDecimal.valueOf(picture.getHeight()), 8, BigDecimal.ROUND_DOWN);
picture.setWidth(picture.getWidth() * rate.floatValue());
picture.setHeight(300);
}

导出效果如下图:

后续有时间再实验一下poi方式的公式导出

参考连接

https://www.e-iceblue.cn/spiredocforjavatext/set-character-format-in-word-in-java.html

使用spire.doc导出支持编辑Latex公式的标准格式word的更多相关文章

  1. Latex公式导出word,Latex转换MathML使用POI导出公式可编辑的Word文件

    背景 之前在 使用spire.doc导出支持编辑Latex公式的标准格式word 博客中写过,使用spire.doc来生成word,不得不说spire.doc的api操作起来还是比较方便,但是使用的过 ...

  2. 使用Spire.Doc来转换文本

    使用Spire.Doc来转换文本 前段时间,我为不熟悉这个产品的读者们写了一篇关于我对 Spire.Doc的初识印象.Spire.Doc是一个专业的Word .NET库,它是专门为开发人员设计的用来快 ...

  3. SPIRE.DOC - .NET开发者的福利

    SPIRE.DOC - .NET开发者的福利 前面我们使用过Spire.XLS for .NET Component创建Excel文件.最近试用了下.DOC 方面的API.这次测试的产品是.通过使用S ...

  4. [.NET] 开头不讲"Hello Word",读尽诗书也枉然 : Word 操作组件介绍 - Spire.Doc

    开头不讲"Hello Word",读尽诗书也枉然 : Word 操作组件介绍 - Spire.Doc [博主]反骨仔 [原文地址]http://www.cnblogs.com/li ...

  5. 开头不讲"Hello Word",读尽诗书也枉然 : Word 操作组件介绍 - Spire.Doc (转)

      [原文地址]http://www.cnblogs.com/liqingwen/p/5898368.html 序 本打算过几天简单介绍下组件 Spire.XLS,突然发现园友率先发布了一篇,既然 x ...

  6. 使用Spire.Doc组件利用模板导出Word文档

    以前一直是用Office的组件实现Word文档导出,但是让客户在服务器安装Office,涉及到版权:而且Office安装,包括权限配置也是比较麻烦. 现在流行使用第三方组件来实现对Office的操作, ...

  7. PowerPoint 中插入 Latex 公式

    做 PPT 用 Latex Beamer 毕竟还是太麻烦,Beamer 毕竟还是更适合学术性的,各种定义各种公式的那种,遇到要画各种图,插入各种图片,进行错综复杂的排版就比较棘手了. 最终还是 Pow ...

  8. 为WLW开发Latex公式插件

    WLW是写博客的利器,支持离线.格式排版等,而且拥有众多的插件.博客园推荐了代码插入插件,但是没有提供WLW的公式编译插件.目前我的一般做法是:先在Word下使用MathType编辑好公式,然后将公式 ...

  9. 【好文翻译】一步一步教你使用Spire.Doc转换Word文档格式

    背景: 年11月,微软宣布作为ECMA国际主要合作伙伴,将其开发的基于XML的文件格式标准化,称之为"Office Open XML" .Open XML的引进使office文档结 ...

随机推荐

  1. [第十六篇]——Docker 安装 CentOS之Spring Cloud直播商城 b2b2c电子商务技术总结

    Docker 安装 CentOS CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise ...

  2. 一文搞懂Python Unittest测试方法执行顺序

    大家好~我是米洛! 欢迎关注我的公众号测试开发坑货,一起交流!点赞收藏关注,不迷路. Unittest unittest大家应该都不陌生.它作为一款博主在5-6年前最常用的单元测试框架,现在正被pyt ...

  3. Alex网络结构

    AlexNet网络结构   网络包含8个带权重的层:前5层是卷积层,剩下的3层是全连接层.最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000类标签的分布网络包含8个带 ...

  4. 有备无患「GitHub 热点速览 v.21.38」

    作者:HelloGitHub-小鱼干 数据库最重要的一个功能是容灾备份,备份不只是对数据库重要,对日常工作生活的我们一样重要,比如花了一个工作日写的代码没有备份(虽然可能只有 1 行-)总归是一个让人 ...

  5. 在PHP中操作临时文件

    关于文件相关的操作,想必大家已经非常了解了,在将来我们刷到手册中相关的文件操作函数时也会进行详细的讲解.今天,我们先来了解一下在 PHP 中关于临时文件相关的一些内容. 获取 PHP 的默认临时创建文 ...

  6. YbtOJ#732-斐波那契【特征方程,LCT】

    正题 题目链接:http://www.ybtoj.com.cn/contest/125/problem/2 题目大意 给出\(n\)个点的一棵树,以\(1\)为根,每个点有点权\(a_i\).要求支持 ...

  7. Git提交时默认编辑器Vim换成Notepad++

    在使用GIT进行commit时,会默认使用Vim,其使用较为笨重,改为Notepad++编辑器较为简便. git commit 默认打开Notepad++编辑器配置: 打开git --- bash,输 ...

  8. 我的Python学习记录

    Python日期时间处理:time模块.datetime模块 Python提供了两个标准日期时间处理模块:--time.datetime模块. 那么,这两个模块的功能有什么相同和共同之处呢? 一般来说 ...

  9. C++学习笔记:09 函数模板与类模板

    课程<C++语言程序设计进阶>清华大学 郑莉老师) 引入 考虑一个求绝对值函数myabs,对于int,double,float等数据类型需要重载多次,编写多个函数体.函数体逻辑代码完全一致 ...

  10. 10.12 LNMP

    yum install nginx php php-fpm mariadb-server php-mysql php.conf server { listen 8000; # pass the PHP ...