使用Java将word解析出来,包含格式和图片

这篇具有很好参考价值的文章主要介绍了使用Java将word解析出来,包含格式和图片。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、需求:

        a. 将word中的内容按照层级结构解析出来

        b. 不区分文件的后缀

        c. 包含word的样式

2、思路:总体思路分为存和取,存的是文档的标题和内容、图片等;取的是文档的树形结构。

        (1). 存:将word中的标题、内容、图片获取出来并进行存储

                a. 上传文档时,获取到文档的名称,存储到数据库表中,产生一个id,即documentId

                b. 解析word之后,按照顺序遍历获取每一个标题进行存储,父标题和子标题之间使用parentId进行关联,即子标题中字段parentId是父标题的id

                c. 在所有的标题中都添加一个documentId方便后期范围查询

                d. 根节点即一级标题的父id为0

                e. 查到的内容如果是p标签,则与自己的上一级进行关联,即p标签的父id为它的上一级标签id

                f. 关联完成之后,生成一个树形结构,并遍历存储到第三方平台的数据库中。

        (2). 取:根据documentId查询该文档的树形结构并返回

                a. 根据documentId查询该文档的所有标题并存储到集合中去

                b. 对集合进行遍历,为了充分使用递归,规定最顶层的标题的父节点为0,从父节点为0的元素开始递归,并将产生的结果生成树形结构并返回。

3、注意:

        (1). 因为自己做的主要是在第三方平台上的操作,所以类似于DmeTestRequestUtil.getDmeResult() 这样的方法主要是跟第三方平台的交互,出于安全性考虑就不放出来了。

         (2). 包含word的样式:要思考的时怎么才能够获得word的样式,即获得html文件

         (3). 在解析的过程中样式是以行内式还是其他的效果呈现:可以转换为行内式

         (4). 为什么不用poi:使用poi最恶心的是要考虑word的版本问题

         (5). 使用的依赖主要是什么:aspose、jsoup

         (6). 层级结构解析主要是判断h、p的顺序关系

4、代码:

        (1). 依赖

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.11.2</version>
</dependency>
<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-words</artifactId>
    <version>15.8.0</version>
</dependency>

        (2). 解析word并保到第三方接口中代码逻辑

/**
     * 解析word
     * @param multipartFile 前端接收的文件,根据自己的需求也可以将MultipartFile转换为File
     * @return TitleTreeVO 存放标题的实体
     * @author WangKuo
     * @date 2023/7/27 11:01
     */
public TitleTreeVO wordAnalysis(MultipartFile multipartFile) throws IOException {
        byte[] byteArr = multipartFile.getBytes();
        InputStream inputStream = new ByteArrayInputStream(byteArr);
        List<DocumentContentVO> documentContentVOList = new LinkedList<>();
        TitleTreeVO titleTreeVO = new TitleTreeVO();
        try {
            // 把流转化为Document
            com.aspose.words.Document doc = new com.aspose.words.Document(inputStream);
            // 设置转化的格式,HtmlSaveOptions转换为HTML格式
            HtmlSaveOptions saveOptions = new HtmlSaveOptions();
            saveOptions.setExportImagesAsBase64(false);
            // 将所有word中的图片放在临时文件夹中,并将html中的链接替换为临时文件夹中绝对路径
            String property = System.getProperty("java.io.tmpdir");
            saveOptions.setImagesFolder(property);
            org.apache.commons.io.output.ByteArrayOutputStream baos = new ByteArrayOutputStream();
            doc.save(baos, saveOptions);
            String token = DmeTestRequestUtil.getToken();
            // 将html文件转化为Document,方便后续使用jsoup的操作
            org.jsoup.nodes.Document htmlDoc = Jsoup.parse(baos.toString());
            // 设置html里面的图片src路径
            this.setImagePath(htmlDoc, token);
            // 存储word文档的名称
            String substring = multipartFile.getOriginalFilename().substring(0, multipartFile.getOriginalFilename().lastIndexOf("."));
            JSONObject docParam = this.getDocParam(substring);
            String saveDocUrl = "https://dme.cn-south-4.huaweicloud.com/rdm_hwdmeverify_app/publicservices/api/DocumentSave/create";
            // 首先根据文档名称生成一条document的数据,产生的id将在标题实体中进行关联
            String dmeResult = DmeTestRequestUtil.getDmeResult(saveDocUrl, docParam, token);
            JSONObject jsonObject1 = JSONObject.parseObject(dmeResult);
            List data1 = jsonObject1.getObject("data", List.class);
            JSONObject jsonObjectData1 = (JSONObject) data1.get(0);
            String id = jsonObjectData1.getString("id");//文档id
            // 存储文档的第一个标题的返回结果,其中包含该节点的id和title
            documentContentVOList = this.exactContentFromHtml(htmlDoc);
            this.dmeSave(documentContentVOList, id, "0", token);//第一个标题的父ID默认为0
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            inputStream.close();
        }
        return titleTreeVO;
    }

/**
  	 * 在解析为html文件的时候需要将图片的地址进行一个替换,由最初的临时文件地址替换为图片在服务器上的位置
     * 设置图片的路径(src)
     * @param document 转换为HTML的文档内容
     * @return void
     * @author Wangkuo
     * @date 2023/7/25 21:40
     */
    private void setImagePath(Document document) throws IOException {
        Elements imgs = document.select("img");
        String token = DmeTestRequestUtil.getToken();
        for (Element img : imgs) {
          	// 获取出html中src内的地址值
            String src = img.attr("src");
          	// 通过地址查到对应的文件
            File file = new File(src);
            FileInputStream input = new FileInputStream(file);
          	// 将file转化为MultipartFile
						MultipartFile multipartFile =new MockMultipartFile("file", file.getName(), "text/plain", IOUtils.toByteArray(input));
            // 该部分主要是第三方接口设置的必须传的参数,在这里我就先设置为定值,因为这些不干扰我的需求结果
						FormVo formVo = new FormVo();
            formVo.setAttributeName("File");
            formVo.setModelName("Document");
            formVo.setApplicationId("-1");
            String uploadImgUrl = "图片作为文件,进行上传";
            String uploadImage = DmeTestRequestUtil.getDmeResultUploadFile(uploadImgUrl, multipartFile, formVo, token);
            JSONObject uploadImgJs = JSONObject.parseObject(uploadImage);
            List data = uploadImgJs.getObject("data", List.class);
          	// 上传完成后,第三方接口会返回一个文件的id,我可以根据这个id进行文件的预览和下载
            String id = (String) data.get(0);
            //上传文件file 并返回上传的路径;将路径拼接出来,并替换到html的document中
            String imgPath = "/api/dme-library/LibraryFolder/preview?fileId="+id;
            img.attr("src",imgPath);
						input.close();
          	// 删除临时文件夹中存储的文件
            file.deleteOnExit();
        }
    }

/**
     * 该部分主要是第三方接口在调用时规定该接口的参数格式
     * 拼接参数
     * @param name 
     * @return com.alibaba.fastjson.JSONObject
     * @author Wangkuo
     * @date 2023/7/27 11:23
     */
    private JSONObject getDocParam(String name) {
        Map<String, Object> mapStr = new HashMap<>();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("name", name);
        mapStr.put("params", paramMap);
        JSONObject jsonObject = new JSONObject(mapStr);
        return jsonObject;
    }

/**
     * 处理树形结构
     * @param htmlDoc 
     * @return java.util.List<DocumentContentVO>
     * @author Wangkuo
     * @date 2023/7/27 11:26
     */
    private List<DocumentContentVO> exactContentFromHtml(Document htmlDoc) throws Exception {
        Elements eleList = htmlDoc.getElementsByTag("h1");
        if (eleList == null || eleList.size() == 0) {
            throw new Exception("上传的文件中不存在一级标题,请检查!");
        }

        Element hElement = htmlDoc.selectFirst("h1");//从第一个标题1 开始往下找
        //Elements pElement = htmlDoc.select("h1");
        List<DocumentContentVO> allTreeList = new ArrayList<>();
        List<DocumentContentVO> list2 = new ArrayList<>();
        List<DocumentContentVO> list3 = new ArrayList<>();
        List<DocumentContentVO> list4 = new ArrayList<>();
        DocumentContentVO b1Map = new DocumentContentVO();
        DocumentContentVO b2Map = new DocumentContentVO();
        DocumentContentVO b3Map = new DocumentContentVO();
        DocumentContentVO b4Map = new DocumentContentVO();
        DocumentContentVO bMap = b1Map;//记录当前map
        //先将第一个标题 放入
        int i = 1;
        b1Map.setTitle(hElement.toString());
        b1Map.setIndex(i);
        allTreeList.add(b1Map);
        while (hElement.nextElementSibling() != null) { //如果存在下一个标题
            i++;
            hElement = hElement.nextElementSibling();
            String nodeName = hElement.nodeName();
            String s = hElement.tagName();
            //System.out.println(s);
            if (Objects.equals(nodeName, "h1")) {
                b1Map = new DocumentContentVO();
                bMap = b1Map;
                b1Map.setTitle(hElement.toString());
                b1Map.setIndex(i);
                allTreeList.add(b1Map);
                list2 = new ArrayList<>();
            } else if (Objects.equals(nodeName, "h2")) {
                b2Map = new DocumentContentVO();
                bMap = b2Map;
                list3 = new ArrayList<>();
                b2Map.setTitle(hElement.toString());
                b2Map.setIndex(i);
                list2.add(b2Map);
                b1Map.setChildList(list2);
            } else if (Objects.equals(nodeName, "h3")) {
                b3Map = new DocumentContentVO();
                bMap = b3Map;
                b3Map.setTitle(hElement.toString());
                b3Map.setIndex(i);
                list3.add(b3Map);
                b2Map.setChildList(list3);
            } else if (Objects.equals(nodeName, "h4")) {
                b4Map = new DocumentContentVO();
                bMap = b4Map;
                b4Map.setTitle(hElement.toString());
                b4Map.setIndex(i);
                list4.add(b4Map);
                b3Map.setChildList(list4);
            } else {
                bMap.setContent(bMap.getContent() == null ? hElement.toString() : bMap.getContent() + hElement.toString());
            }
        }
        return allTreeList;
    }

/**
     * 传入html解析的树 和对应文档id 通过递归实现保存
     *
     * @param treeList
     * @param id
     * @param parentId
     * @return java.lang.String
     * @author Wangkuo
     * @date 2023/7/25 16:48
     */
    private String dmeSave(List<DocumentContentVO> treeList, String id, String parentId,String token) {
        String dmeResult = null;
        for (DocumentContentVO documentContentVO : treeList) {
            if (documentContentVO != null) {
                String title = documentContentVO.getTitle();
                int sort = documentContentVO.getIndex();
                String content = documentContentVO.getContent();
                String url = "创建对应数据的第三方url";
                JSONObject jsonObjectParam = this.paramJoint1(title, id, parentId, sort, content);
                dmeResult = DmeTestRequestUtil.getDmeResult(url, jsonObjectParam, token);
                List data = JSONObject.parseObject(dmeResult).getObject("data", List.class);
                if (data != null && !data.isEmpty()) {
                    JSONObject jsonObject = (JSONObject) data.get(0);
                    String parentIdNext = jsonObject.getString("id");
                    if (documentContentVO.getChildList() != null && documentContentVO.getChildList().size() > 0) {
                        dmeSave(documentContentVO.getChildList(), id, parentIdNext,token);
                    }
                }
            }
        }
        return dmeResult;
    }

/**
     * 同理,第三方接口规定的参数样式,需要进行拼接
     * @param title
     * @param id
     * @param parentId
     * @param sort
     * @param content 
     * @return com.alibaba.fastjson.JSONObject
     * @author Wangkuo
     * @date 2023/7/27 11:30
     */
    private JSONObject paramJoint1(String title, String id, String parentId, int sort, String content) {
        Map<String, Object> mapStr = new HashMap<>();
        Map<String, Object> paramsMap = new HashMap<>();
        if (id != null) {
            paramsMap.put("title", title);
            paramsMap.put("sort", sort);
            paramsMap.put("parentId", parentId);
            paramsMap.put("content", content);
            paramsMap.put("documentId", id);
        } else {
            paramsMap.put("title", title);
        }
        mapStr.put("params", paramsMap);
        return JSONObject.parseObject(JSON.toJSONString(mapStr));
    }

        (3). 根据documentId查询该篇文档的标题内容树形结构文章来源地址https://www.toymoban.com/news/detail-738777.html

/**
 * 根据documentId查询对应的word文档的树形结构
 * @param reqJSON {"id":"525663360008593408"}
 * @return java.util.List<TitleTreeVO>
 * @author Wangkuo
 * @date 2023/7/27 11:32
 */
public List<TitleTreeVO> getTreeCon(JSONObject reqJSON) {
    String id = reqJSON.getString("id");
    List<TitleTreeVO> allTitleByDocId = this.getAllTitleByDocId(id);
    TitleTreeVO titleTreeVO = new TitleTreeVO();
    titleTreeVO.setId("0");
    this.getChild(titleTreeVO,allTitleByDocId);
    return titleTreeVO.getChildList();
}

/**
     * 根据文档id获取到该文档的所有标题(此时获取的集合没有父子级关系)
     * @param docId 
     * @return java.util.List<TitleTreeVO>
     * @author Wangkuo
     * @date 2023/7/27 11:34
     */
    private List<TitleTreeVO> getAllTitleByDocId(String docId) {
        String url = "第三方标题表的查询";
				// 参数拼接
        JSONObject docIdParam = getDocIdParam(docId);
        String token = DmeTestRequestUtil.getToken();
        String dmeResult = DmeTestRequestUtil.getDmeResult(url, docIdParam, token);
        JSONObject jsonObject = JSONObject.parseObject(dmeResult);
        List data = jsonObject.getObject("data", List.class);
        List<TitleTreeVO> titleList = new ArrayList<>();
        if (data != null && !data.isEmpty()) {
            for (Object title : data) {
                JSONObject titleJson = (JSONObject)title;
                TitleTreeVO titleTreeVO = new TitleTreeVO();
                titleTreeVO.setContent(titleJson.getString("content"));
                titleTreeVO.setTitle(titleJson.getString("title"));
                titleTreeVO.setId(titleJson.getString("id"));
                titleTreeVO.setIndex(Integer.parseInt(titleJson.getString("sort")));
                titleTreeVO.setDocumentId(titleJson.getString("documentId"));
                titleTreeVO.setParentId(titleJson.getString("parentId"));
                titleList.add(titleTreeVO);
            }
        }
        return titleList;
    }

/**
     * 通过递归获取到各级的子标题和内容
     * @param parentTitleTreeVO
     * @param titleListOld
     * @return TitleTreeVO
     * @author Wangkuo
     * @date 2023/7/27 11:42
     */
    private TitleTreeVO getChild(TitleTreeVO parentTitleTreeVO,List<TitleTreeVO> titleListOld) {
        List<TitleTreeVO> titleList = new ArrayList<>();
        if (titleListOld != null && titleListOld.size()>0) {
            List<TitleTreeVO> titleCollect = titleListOld.stream().filter(e -> e.getParentId().equals(parentTitleTreeVO.getId())).collect(Collectors.toList());
            if(titleCollect.size()>0){
                for (TitleTreeVO title : titleCollect) {
                    TitleTreeVO titleTreeVO = new TitleTreeVO();
                    titleTreeVO.setIndex(title.getIndex());
                    titleTreeVO.setTitle(title.getTitle());
                    titleTreeVO.setId(title.getId());
                    titleTreeVO.setContent(title.getContent());
                    titleTreeVO.setDocumentId(title.getDocumentId());
                    titleTreeVO.setParentId(title.getParentId());
                    titleList.add(titleTreeVO);
                    this.getChild(titleTreeVO,titleListOld);
                }
            }
        }
        List<TitleTreeVO> titleSortList = titleList.stream().sorted(Comparator.comparing(TitleTreeVO::getIndex)).collect(Collectors.toList());
        parentTitleTreeVO.setChildList(titleSortList);
        return parentTitleTreeVO;
    }

到了这里,关于使用Java将word解析出来,包含格式和图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java使用poi解析word表格,把数据入库

    77、java解析word表格,把数据入库

    2023年04月09日
    浏览(42)
  • java 使用POI-TL根据word模版,生成word文件,含图片,富文本。

    1.引入mavna坐标` 2 .poi-tl-ext插件主要用于富文本内容格式在word展现 3.word模版创建 3.具体代码实现 4.本文的miniourl路径实质为网络路径的文件。

    2024年02月16日
    浏览(68)
  • 在java中如何使用openOffice进行格式转换,word,excel,ppt,pdf互相转换

    1.首先需要下载并安装openOffice,下载地址为: Apache OpenOffice download | SourceForge.net 2.安装后,可以测试下是否可用; 3.build.gradle中引入依赖: 4.创建工具类,启动openOffice服务的方法 5.结束openOffice服务的方法 7.在测试方法中进行格式转换,如,他可以是任意类型转换,如excel转换

    2024年02月14日
    浏览(57)
  • java超简单实现文档在线预览功能,支持word\excel\text\pdf\图片等格式转pdf,aspost 转pdf部署linux中文乱码解决方案

    一、背景         在工作中需要对上传到服务器的各种类型包括但不限于word、pdf、excel等文件进行在线预览,前端比较菜搞不定,只能本人亲自上。         网上的经验比较多也比较乱, 有的只有预览,没有文件格式转换,有的也不说linux存在字体问题, 本文会直白的给

    2024年04月10日
    浏览(147)
  • Java通过InputStream判断word格式

    Java通过InputStream判断word格式)

    2024年02月15日
    浏览(47)
  • Java使用POI解析带图片的excel,简洁好用

            这天遇到这个这样的需求,需要导入表格中的数据,还得支持带图片;这应该难不倒咱阿里的EasyExcel,打开官网文档一看哦豁,明确表示暂时不支持解析带图片的Excel...... 好了,这下只能看POI了,然后想起来项目里引入的HuTools工具类,它应该封装好了吧;于是决定用

    2024年02月11日
    浏览(39)
  • Java版Word开发工具Aspose.Words基础教程:检测文件格式并检查格式兼容性

    Aspose.Words for Java是功能丰富的文字处理API,开发人员可以在自己的Java应用程序中嵌入生成,修改,转换,呈现和打印Microsoft Word支持的所有格式的功能。它不依赖于Microsoft Word,但是它提供了Microsoft Word通过其API支持的功能。 Aspose.Words for Java最新下载 https://www.evget.com/product/

    2024年02月14日
    浏览(53)
  • java导出word(含图片、表格)

    1.pom 引入 2.java代码示例 3.效果展示

    2024年02月07日
    浏览(47)
  • Java word文档转图片 || word转pdf两行代码搞定

    目录 一、首先引入我们需要的依赖。 二、准备一个word文档模板,使用{{}}定义我们需要填充的数据。 三、word文档动态数据填充转换图片demo示例 四、poi-tl(poi template language)Word模板引擎 五、把demo示例简化封装成Controller接口层 六、word文档生成动态数据转换成pdf 一、首先引

    2024年02月06日
    浏览(52)
  • java poi 获取excel中的图片(包含wps中嵌入单元格图片)

    项目中有excel导入功能,并且需要导入excel中的图片;模板如图: 已知office中插入的图片为浮动形式;如图: wps中可以插入浮动图片,也可以插入嵌入单元格图片;如图: 并且在wps嵌入单元格形式的图片可以看到使用的是公式;如图:  问题来了,如何获取图片  并且将图片与单元格进行对

    2024年02月07日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包