当前位置: 首页 > news >正文

java中,怎样用最简单方法实现写word文档

在跨平台环境中实现写word时,如果用现成的库,就会涉及跨平台兼容性问题,比如在安卓与java中实现写word的功能。还有一个问题就是,完全用程序生成word文档,工作量较大。所以采用了模板替换的方法。

docx文档本质就是一个zip文件,只要将它的扩展名改成zip,就能解压出一系列的xml文件与图片文件,它的目录结构如下:

  1. [Content_Types].xml:定义了文档中所有文件的 MIME 类型。

  2. _rels/:包含了文档的元数据和关系信息,有一个特殊的文件 .rels,定义了文档的内部链接和外部链接。

  3. docProps/:这个文件夹包含文档的属性信息,如标题、作者、主题等。

    • app.xml:包含应用程序特定的属性;
    • core.xml:包含核心属性,如标题、作者、创建日期等;
    • custom.xml:包含自定义元数据。
  4. word/:这个文件夹包含文档的主要内容和设置。

    • document.xml:这是文档的主要 XML 文件,包含了文本、样式、段落、表格和其他内容;
    • footer1.xml:页脚;
    • header1.xml:页眉;
    • styles.xml:包含文档中使用的样式定义;
    • settings.xml:包含文档的设置,如页面布局、标题等;
    • fontTable.xml:包含文档中使用的字体列表;
    • numbering.xml:包含文档中的编号格式定义;
    • theme/:包含文档的主题信息,如颜色方案、字体方案等;
    • media/:包含文档中使用的图像和其他媒体文件。

DOCX 文件的 XML 结构是层次化的,通常以 w:document 作为根元素,然后包含以下主要部分:

  • w:body:包含文档的主体内容,如段落 (w:p)、表格 (w:tbl)、图片 (w:drawing) 等;
  • w:p:段落元素,包含文本和格式化信息;
  • w:r:运行元素,表示文本的一段连续区域,可以包含文本 (w:t) 和格式化信息;
  • w:t:文本元素,包含实际的文本内容;
  • w:tbl:表格;
  • w:tr,w:tc:表格中的行与列。

每个 XML 文件都遵循 OOXML 的命名空间规则,并且使用特定的 XML 模式进行定义。

主要内容在word目录下,通常关注word目录下的document.xml,header1.xml、footer1.xml以及media子目录下的图片文件。

在程序中产生的数据,通常是规则的,比如表格数据(如下图),非常适合传给freemarker,由它替换到word目录下三个xml文件以及media子目录下的文件。注意:图片不能用base64格式,需要将它转成二进制格式,一个小遗憾,如果能用,模板定义就更简单了。

模板制作方法也很简单:用office或wps写一个文档,定义好格式,在需要占位的地方写上特定的内容(只要在xml中容易找到就可以)。然后将docx扩展名改成zip,解压后,在word目录下的document.xml,header1.xml、footer1.xml中,将内容都改成指定的占位符就行了。

freemarker的语法这里就不介绍了。freemarker在安卓中有点点问题,具体不记得了。我用的是js,把几个xml文档改成js程序,样例如下:

var xml=[];
xml.push(`....`);
if(conditions...) xml.push(`....`)
.....
xml.join('');//输出最后的内容

把它们放到一个js引擎中,比如graalvm的js引擎,安卓上的quickjs引擎等,因为都是基本js语法,不会有兼容性问题。js执行的最终输出结果就是所需的xml文档。

生成完毕,按原来的结构压缩成zip包,再改成docx扩展名就可以了。

至简网格的服务器要在java与安卓中都能运行,兼容性就是个大问题,并且资源占用不可能像普通服务器那样没有节制,所以用的就是这种方法。因为本身要用js引擎做接口实现的扩展,所以js引擎是必须的,顺带着,部分模板就用js实现拼接。

http://www.lryc.cn/news/358413.html

相关文章:

  • 大语言模型的工程技巧(三)——分布式计算
  • AI开发初体验:昇腾加持,OrangePi AIpro 开发板
  • 微服务架构下Docker容器技术与Kubernetes(K8S)
  • 风萧萧兮易水寒,壮士一去兮不复还 的 rm 命令
  • How Diffusion Models Work
  • antd table列选中效果实现
  • Golang实现文件复制
  • 探秘SpringBoot默认线程池:了解其运行原理与工作方式(@Async和ThreadPoolTaskExecutor)
  • kubernetes(Jenkins、kubernetes核心、K8s实战-KubeSphere、)
  • 国际数字影像产业园|科技与文创产品创意集市,共筑创新文化新高地
  • leetcode-55 跳跃游戏
  • Vue——计算属性 computed 与方法 methods 区别探究
  • Java中的ORM框架——myBatis
  • vue2生命周期和计算属性
  • Hadoop3:MapReduce之简介、WordCount案例源码阅读、简单功能开发
  • centos8stream 编译安装 php-rabbit-mq模块
  • 「异步魔法:Python数据库交互的革命」(二)
  • php正则中的i,m,s,x,e分别表示什么
  • 最新!2023年台湾10米DEM地形瓦片数据
  • 网络学习(11) |深入解析客户端缓存与服务器缓存:HTTP缓存控制头字段及优化实践
  • uniapp中二次封装jssdk和使用
  • 只刷题可以通过PMP考试吗?
  • Python Selenium 详解:实现高效的UI自动化测试
  • npm获取yarn在安装依赖时 git://github.com/user/xx.git 无法访问解决方法 -- 使用 insteadOf设置git命令别名
  • Centos7网络故障,开机之后连不上网ens33mtu 1500 qdisc noop state DOWN group default qlen 1000
  • 分析 Base64 编码和 URL 安全 Base64 编码
  • cocos 屏幕点击坐标转换为节点坐标
  • 电瓶车进电梯识别报警摄像机
  • 数据库到服务器提权
  • 【MySQL精通之路】InnoDB(9)-表和页压缩(1)-表压缩