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


    前言

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

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

    在这里插入图片描述

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

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

    然后

    
    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");
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284

    接下来的步骤和上一篇一摸一样,打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());
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

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

            /*创建表格*/
            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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

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

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

        //待修改的元素索引集合
        public static Set<Integer> set = new HashSet<Integer>();
    
        //    记录待修改的元素索引
        public static void getEditIndex(int index) {
            set.add(index);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

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

    然后在处理函数中去除高亮,这里利用了 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1. 关于拿数据部分的疑问
      这部分可以看看我上一篇文章(本篇开头有跳转链接)

    尾声

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

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

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

  • 相关阅读:
    xLua热更新(一)xLua基本使用
    微搭低代码中实现增删改查
    编译原理:上下文无关文法 CFG
    神器必会!特别好使的编辑器Source Insight
    Nginx 安装配置和实际使用
    Python读写文本、图片、xml
    ChatGPT的增长已经进入了瓶颈期
    leetcode做题笔记204. 计数质数
    React基础-JSX事件绑定-事件传参
    Replication(上):常见复制模型&分布式系统挑战
  • 原文地址:https://blog.csdn.net/qq_41997592/article/details/126443931