【生产力++】脚本自动化提取待复习内容 极大提高复习效率(下)

前言

前不久,我为了提高考研英语的复习效率,随手写了个小脚本——自动提取待复习单词

【插入一句】有兴趣的朋友可以来看看,或许可以帮助到你
传送门(第一版)

在这里插入图片描述

经过几天的使用,我发现复习效率确实变高啦,不用像以前那样一页页翻文档,英语真题词汇的复习时长也终于落在一个比较合理的区间。

但是随之而来我又发现了另一个问题,我确实可以快速把所有待复习单词整理出来,但是我通过复习,那些逐步掌握的单词(后续可能不太需要继续复习)没有办法实现自动去除高亮,这就会导致我们还必须手动回到文档然后把它去掉…这显然又提升了自己的工作量…又回到了最初的起点。
在这里插入图片描述
于是我便基于此,继续完善了这个小脚本,于是就有了这个小脚本2.0版本。

先给大家看看效果!

效果展示

还是咱们熟悉的脚本开始!!
在这里插入图片描述
wow!!!!!虽然上次说自己懒不想做界面哈哈,光速打脸。(本人java GUI真的太菜,请忽视丑丑的界面)

所有单词会整齐地躺在这里
在这里插入图片描述
接下来,当然是来测试一下新功能:去除那些已经不需要再次复习的单词的高亮。当然,大家可能会发现这个界面既没有多选框,又没有按钮,那应该怎么选择单词…

比如我们文档中是这样的,我们想要把这两个单词的高亮去除
在这里插入图片描述
我们只需要单击,会有一个极其简陋的渲染提醒你,你已经选上了。
在这里插入图片描述
然后再点下一个(是的这里没有保留上一个的渲染 嘻嘻,但是后台已经记住了这个需要去除高亮的单词,并且我设置了防重复,所以就算你点好几次也没关系)
在这里插入图片描述
然后我们假装自己已经复习完了,可以关闭窗口了。

观众可能会问:???这就好了

接下来我们去文档看看是不是去除了高亮
在这里插入图片描述
再次运行脚本,确实已经没有这两个词了
在这里插入图片描述

好啦,演示结束,或许样式一般,交互性也没有那么舒服,但毕竟效率至上 ,咱就一切从简了,能用就行。

实现

思路梳理

实现步骤很清晰:

  1. 从word文档拿到待复习数据 (上一版已实现)
    利用实体类和List把所有数据保存起来

  2. 使用java GUI创建一个窗体表格,并作初始化(待实现)
    随便调调样式,设置设置窗体大小之类的

  3. 把数据赋值给表格(待实现)
    通过迭代器把List赋值给表格

  4. 设置一下监听事件(单击监听事件 窗口关闭监听事件)(待实现)
    需要做的事有两件:
    ①记录鼠标点击的行的下标
    ②在窗口关闭时根据保存的下标来去除文档高亮

代码部分

接下来直接上代码(相关开发环境和上一版一摸一样)
先来个实体类吧,单词和中文应该是一个整体

import lombok.Data;

@Data
public class Word {
    private String english;
    private String chinese;
}

然后


import com.spire.doc.Document;
import com.spire.doc.Section;
import com.spire.doc.TableCell;
import com.spire.doc.TableRow;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.documents.TextSelection;
import com.spire.doc.fields.TextRange;
import com.spire.doc.interfaces.ITable;

import java.awt.*;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.*;
import java.util.List;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;


public class word_op_2 extends JFrame {

    public static void main(String[] args) {
//          拿数据
        getWords();
//          分数据
        operateWords();
//          构建图形化界面
        new word_op_2();
    }

    //======拿到文档数据==================================================================================================

    //所有待复习单词原始数据
    public static List<Word> words = new ArrayList<>();
    //临时存储器
    public static Word word = new Word();

    public static void getWords() {

        //加载Word源文档
        Document doc = new Document();
        doc.loadFromFile("C:\\Users\\23252\\Desktop\\真题词汇词组.docx");

        //获取第一节
        Section section = doc.getSections().get(0);

        for (int i = 0; i < section.getTables().getCount(); i++) {
            //获取第i个表格
            ITable table = section.getTables().get(i);

            //遍历每个表格的行
            for (int j = 0; j < table.getRows().getCount(); j++) {
                TableRow row = table.getRows().get(j);

                //遍历每行的列
                for (int k = 0; k < row.getCells().getCount(); k++) {
                    TableCell cell = row.getCells().get(k);

                    //某个单元格整体的内容
                    StringBuilder res = new StringBuilder();

                    //遍历单元格中的段落
                    for (int l = 0; l < cell.getParagraphs().getCount(); l++) {
                        Paragraph paragraph = cell.getParagraphs().get(l);
                        //遍历每个段落的子对象
                        for (int m = 0; m < paragraph.getChildObjects().getCount(); m++) {
                            Object obj = paragraph.getChildObjects().get(m);
                            if (obj instanceof TextRange) {
                                //获取文本
                                String text = ((TextRange) obj).getText();
                                //去除特殊符号
                                text = text.replaceAll("\r|\n", "");
                                //获取文本的高亮颜色(即突出显示颜色)
                                Color color = ((TextRange) obj).getCharacterFormat().getHighlightColor();
                                //判断是否高亮
                                if (!(color.getRGB() == 0)) {
                                    res.append(text);
                                    //判断是否有多段 进行分割
                                    if (cell.getParagraphs().getCount() != 1 && m == paragraph.getChildObjects().getCount() - 1) {
                                        //最后一段后面没东西 不需要再加分割
                                        if (cell.getParagraphs().getCount() - 1 != l) {
                                            res.append(" | ");
                                        }
                                    }
                                }
                            }
                        }

                    }

                    if (!res.toString().equals("")) {
                        //判断奇偶列
                        if ((k + 1) % 2 != 0) {
                            word.setEnglish(res.toString());

                        } else {
                            word.setChinese(res.toString());

                            Word temp = new Word();
                            temp.setEnglish(word.getEnglish());
                            temp.setChinese(word.getChinese());
                            words.add(temp);
//                            清空全局变量
                            word.setChinese(null);
                            word.setEnglish(null);
                        }
                    }
                }
            }

        }
    }

    //======构建页面表格==================================================================================================

    //表格
    static JTable table;

    public word_op_2() {

        setSize(600, 600);
        setLocationRelativeTo(null);

        /*创建表格*/
        DefaultTableModel model = new DefaultTableModel();
        model.addColumn("英文", new Vector<>(english_list));
        model.addColumn("", new Vector<String>());
        model.addColumn("", new Vector<String>());
        model.addColumn("", new Vector<String>());
        model.addColumn("汉语", new Vector<>(chinese_list));


        table = new JTable(model);

        JScrollPane jp = new JScrollPane(table);

        JTableHeader head = table.getTableHeader();
        //设置表头的大小
        head.setPreferredSize(new Dimension(head.getWidth(), 30));
        //设置表头字体大小
        head.setFont(new Font("宋体", Font.BOLD, 16));
        //设置表格的行宽
        table.setRowHeight(30);
        //设置表格行中字体大小
        table.setFont(new Font("宋体", Font.ROMAN_BASELINE, 13));
        /*设置表格中的内容居中*/
        DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        renderer.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
        table.setDefaultRenderer(Object.class, renderer);

        this.add(jp);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //单机事件监听
        table.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                getEditIndex(table.getSelectedRow());
            }

            @Override
            public void mousePressed(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {

            }

            @Override
            public void mouseExited(MouseEvent e) {

            }
        });


        //页面窗口状态监听(这里只用了关闭页面去除高亮)
        addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {

            }

            @Override
            public void windowClosing(WindowEvent e) {
                //如果没做修改 就不需要重新保存文件了
                if (set.size() != 0) {
                    removeHeightLight();
                }
            }

            @Override
            public void windowClosed(WindowEvent e) {

            }

            @Override
            public void windowIconified(WindowEvent e) {

            }

            @Override
            public void windowDeiconified(WindowEvent e) {

            }

            @Override
            public void windowActivated(WindowEvent e) {

            }

            @Override
            public void windowDeactivated(WindowEvent e) {

            }
        });

    }

    //======把源数据分类==================================================================================================

    //    中文列  英文列
    public static List<String> chinese_list = new ArrayList<>();
    public static List<String> english_list = new ArrayList<>();

    //将单词数据分为中文和英文两列 方便迭代器使用
    public static void operateWords() {
        for (Word value : words) {
            english_list.add(value.getEnglish());
            chinese_list.add(value.getChinese());
        }
    }

    //======为关闭页面最准备===============================================================================================

    //待修改的元素索引集合
    public static Set<Integer> set = new HashSet<Integer>();

    //    记录待修改的元素索引
    public static void getEditIndex(int index) {
        set.add(index);
    }

    //======关闭页面并去除高亮=============================================================================================

    //    窗口关闭之后的高亮删除操作
    public static void removeHeightLight() {

        //加载Word源文档
        Document doc = new Document();
        doc.loadFromFile("C:\\Users\\23252\\Desktop\\真题词汇词组.docx");

        for (Integer i : set) {
            // 搜索关键字段落
            TextSelection[] englishSelections = doc.findAllString(words.get(i).getEnglish(), false, false);
            TextSelection[] chineseSelections = doc.findAllString(words.get(i).getChinese(), false, false);

            //去除高亮
            for (TextSelection english : englishSelections) {
                english.getAsOneRange().getCharacterFormat().setHighlightColor(null);
            }

            for (TextSelection chinese : chineseSelections) {
                chinese.getAsOneRange().getCharacterFormat().setHighlightColor(null);
            }

        }
        doc.saveToFile("C:\\Users\\23252\\Desktop\\真题词汇词组.docx");

    }
}

接下来的步骤和上一篇一摸一样,打jar包,写bat启动脚本,不知道的兄弟可以看上一篇哈

一些解释

  1. 这里为什么要把数据分成两个List
    //    中文列  英文列
    public static List<String> chinese_list = new ArrayList<>();
    public static List<String> english_list = new ArrayList<>();

    //将单词数据分为中文和英文两列 方便迭代器使用
    public static void operateWords() {
        for (Word value : words) {
            english_list.add(value.getEnglish());
            chinese_list.add(value.getChinese());
        }
    }

这个问题需要结合给列表赋值的代码来说

        /*创建表格*/
        DefaultTableModel model = new DefaultTableModel();
        model.addColumn("英文", new Vector<>(english_list));
        model.addColumn("", new Vector<String>());
        model.addColumn("", new Vector<String>());
        model.addColumn("", new Vector<String>());
        model.addColumn("汉语", new Vector<>(chinese_list));

第一个原因是 :在初始化表格的时候我们发现它是把迭代器作为参数的,那就意味着放进迭代器里的第一级的东西他会帮你一个个遍历,但如果更深入的东西他就不会帮你遍历了。就像这样,迭代器只会帮你把一个个对象取出打印到页面上,而不会把英文和中文打印出来。
在这里插入图片描述
第二个原因:我们通过实操不难发现,表格要么是按列为单位添加,要么是按行为单位来添加,所以拆开之后一列全是英语,一列全是中文,正好方便插入。

  1. 怎么实现的去除高亮
    首先在点击时出发监听函数
            @Override
            public void mouseClicked(MouseEvent e) {
                getEditIndex(table.getSelectedRow());
            }

在处理函数内记住需要去除高亮的下标,这里选择 HashSet 的一个主要原因是因为它可以过滤重复元素,可以为后台处理减少很多不必要的重复操作

    //待修改的元素索引集合
    public static Set<Integer> set = new HashSet<Integer>();

    //    记录待修改的元素索引
    public static void getEditIndex(int index) {
        set.add(index);
    }

在用户关闭脚本的时候,触发监听函数(这里也是做个小小的判断,提高运行效率)

            @Override
            public void windowClosing(WindowEvent e) {
                //如果没做修改 就不需要重新保存文件了
                if (set.size() != 0) {
                    removeHeightLight();
                }
            }

然后在处理函数中去除高亮,这里利用了 Hashset中的下标和我们最初的源数据下标是一致的。所以直接拿来用就行了。(注意中英文都要去除高亮哦)

 //    窗口关闭之后的高亮删除操作
    public static void removeHeightLight() {

        //加载Word源文档
        Document doc = new Document();
        doc.loadFromFile("C:\\Users\\23252\\Desktop\\真题词汇词组.docx");

        for (Integer i : set) {
            // 搜索关键字段落
            TextSelection[] englishSelections = doc.findAllString(words.get(i).getEnglish(), false, false);
            TextSelection[] chineseSelections = doc.findAllString(words.get(i).getChinese(), false, false);

            //去除高亮
            for (TextSelection english : englishSelections) {
                english.getAsOneRange().getCharacterFormat().setHighlightColor(null);
            }

            for (TextSelection chinese : chineseSelections) {
                chinese.getAsOneRange().getCharacterFormat().setHighlightColor(null);
            }

        }
        doc.saveToFile("C:\\Users\\23252\\Desktop\\真题词汇词组.docx");

    }
}
  1. 关于拿数据部分的疑问
    这部分可以看看我上一篇文章(本篇开头有跳转链接)

尾声

到这里,这一版的改动已经达到了我的预期,如果不出意外这应该就是最终版了。

但其实根据每个人的不同需求,还可以继续添加一些其他功能,比如从文档中随机出来几十个单词,不会的标记好,然后添加高亮…等等等等

那么,继续去内卷啦,希望这个脚本可以帮助到需要的朋友们。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AntyRia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值