使用poi实现word解析

使用poi实现word解析

word样式解析

poi进行样式解析时,如果是常用的样式是无法获取到它的样式信息的,并且通过poi工具读取时也存在有部分内容无法解析,这样在使用的时候体验就不是太好,后来我发现将docx文件通过压缩包的形式打开,docx的文件打开如图所示

在这里插入图片描述

打开“word”,里面有一个document.xml这个文件就包含了word的样式以及文本内容

在这里插入图片描述

通过分析此文件可以发现

w:p:表示属于文本内容

w:val: 表示文本的字体大小

w:ascil: 表示文本的字体格式

如果 w:p 中的文本为空则表示该段落没有文本内容,字体格式获取时为空则表示字体使用的是默认格式宋体(简),字体大小如果获取为空,表示字体使用的是默认字体大小24.

springBoot集成poi解析word文件

1.导入maven依赖

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.5</version>
        </dependency>

2.编写操作word工具类PoiUtil

 public static Map<String, FontDto> getType(MultipartFile file) {
        HashMap<String, FontDto> fontMap = new HashMap<>(20);
        try (ZipInputStream zipIs = new ZipInputStream(file.getInputStream())) {
            // 读取 Word 文档
            ZipEntry entry;
            String contentXml = null;

            // 寻找 content.xml 文件
            while ((entry = zipIs.getNextEntry()) != null) {
                if ("word/document.xml".equals(entry.getName())) {
                    // 找到了 content.xml
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = zipIs.read(buffer)) > 0) {
                        baos.write(buffer, 0, len);
                    }
                    contentXml = baos.toString("UTF-8");
                    baos.close();
                    break;
                }
            }
            if (contentXml != null) {
                // 解析 content.xml
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                Document doc = db.parse(new ByteArrayInputStream(contentXml.getBytes(StandardCharsets.UTF_8)));
                // 查找标题的字体信息(假设标题在第一个段落中)
                NodeList textNodes = doc.getElementsByTagName("w:p");
                for (int i = 0; i < textNodes.getLength(); i++) {
                    Element textNode = (Element) textNodes.item(i);
                    String text = textNode.getTextContent().trim();
                    if ("".equals(text)) {
                        continue;
                    }
                    // 获取格式信息
                    String fontFamily = null;
                    String fontSize = null;
                    // 获取包含格式信息的父节点
                    Element parentNode = (Element) textNode.getElementsByTagName("w:r").item(0);
                    if (parentNode != null) {
                        NodeList fontNodes = parentNode.getElementsByTagName("w:rPr");
                        if (fontNodes.getLength() > 0) {
                            Element fontNode = (Element) fontNodes.item(0);
                            Element fontFamilyNode = (Element) fontNode.getElementsByTagName("w:rFonts").item(0);
                            if (fontFamilyNode != null) {
                                fontFamily = fontFamilyNode.getAttribute("w:ascii");
                                if ("".equals(fontFamily)) {
                                    fontFamily = fontFamilyNode.getAttribute("w:cs");
                                    if ("".equals(fontFamily)) {
                                        fontFamily = "汉仪书宋一简";
                                    }
                                }
                            }
                            Element fontSizeNode = (Element) fontNode.getElementsByTagName("w:sz").item(0);
                            if (fontSizeNode != null) {
                                fontSize = fontSizeNode.getAttribute("w:val");
                            } else {
                                // 默认字体大小
                                fontSize = "24";
                            }
                        }
                    }
                    FontDto fontDto = new FontDto();
                    fontDto.setFont(fontFamily);
                    fontDto.setFontSize(fontSize);
                    fontMap.put(text, fontDto);
                }
            } else {
                throw new RuntimeException("文件中不存在这样的数据");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fontMap;
    }


    public static Boolean checkBold(XWPFParagraph paragraph) {
        List<XWPFRun> runs = paragraph.getRuns();
        for (XWPFRun run : runs) {
            if (run.isBold()) {
                return true;
            }
        }
        return false;
    }

    public static Boolean checkBold(XWPFTableCell cell) {
        for (XWPFParagraph paragraph : cell.getParagraphs()) {
            // 检查段落对齐方式
            ParagraphAlignment alignment = paragraph.getAlignment();
            boolean isCenterAligned = alignment == ParagraphAlignment.CENTER;

            // 遍历段落中的所有文本运行,检查加粗属性
            for (XWPFRun run : paragraph.getRuns()) {
                return run.isBold();
            }
        }
        return false;
    }

    public static Boolean checkCenter(XWPFTableCell cell) {
        for (XWPFParagraph paragraph : cell.getParagraphs()) {
            // 检查段落对齐方式
            ParagraphAlignment alignment = paragraph.getAlignment();
            if (alignment == ParagraphAlignment.CENTER) {
                return true;
            }
        }
        return false;
    }

    public static Boolean checkCenter(XWPFParagraph paragraph) {
        ParagraphAlignment alignment = paragraph.getAlignment();
        if (alignment == ParagraphAlignment.CENTER) {
            return true;
        }
        return false;
    }

fontDto类:

public class FontDto {

    private String font;

    private String fontSize;

    public String getFont() {
        return font;
    }

    public void setFont(String font) {
        this.font = font;
    }

    public String getFontSize() {
        return fontSize;
    }

    public void setFontSize(String fontSize) {
        this.fontSize = fontSize;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        FontDto fontDto = (FontDto) o;
        return Objects.equals(font, fontDto.font) &&
                Objects.equals(fontSize, fontDto.fontSize);
    }

    @Override
    public int hashCode() {
        return Objects.hash(font, fontSize);
    }
}

这里只展示了获取word中每个段落的样式,在不同的需求中基本都会解析获取样式信息。如果只解析文档文字部分内容,直接调用上述的方法即可。获取Map是为了再一次解析文件保存文本内容时能够直接获取到当前文本的样式信息。解析文本的信息依旧采用poi的方式进行解析。

3.调用解析方法

    @PostMapping("/word")
    public ApiResult<List<FontDto>> analyzeWord(@RequestPart("file")MultipartFile file){
        return ApiResult.success(service.analyzeWord(file));
    }

3.调用解析方法

    @PostMapping("/word")
    public ApiResult<List<FontDto>> analyzeWord(@RequestPart("file")MultipartFile file){
        return ApiResult.success(service.analyzeWord(file));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值