精华内容
下载资源
问答
  • 一:场景 通过Word模板来实现动态的word生成二: 基本要求 1:替换文本中的内容 ...使用方法:直接读取word文件,替换里面各个部分内容 优点:直接使用word文件作为模板 缺点:本身的替换逻辑无法保留格式四:

    一:场景
    通过Word模板来实现动态的word生成

    二: 基本要求
    1:替换文本中的内容
    2:替换表格中的内容(不用动态生成表格)
    3:替换后的内容应该与替换前的内容格式相同
    4:模板修改方便
    5:效果如下:
    模板:
    这里写图片描述
    结果:
    这里写图片描述
    三:poi分析
    使用方法:直接读取word文件,替换里面各个部分的内容
    优点:直接使用word文件作为模板
    缺点:本身的替换逻辑无法保留格式

    四:为什么选择封装POI
    1:因为时间和学习成本(懒)的问题,没有研究docx的xml规则,因此决定直接对现有的工具进行封装,来实现需求.

    2:freeMarker本身只是对通用的模板进行处理,底层并不能直接解析word文件.
    而poi本身就是对word文件进行操作的,因此可以对直接在poi的api上进一步的封装.

    五:可行性分析
    1.POI使用XWPFDocument对象来解析docx的文件,通过在构造时传入docx文件的读取流完成解析过程,将解析后将信息分门别类的存储在不同的对象中.并提供write(OutputStream stream)方法将这些对象重新转换为xml写入到文件中.

    2.XWPFDocument中的对象存储有文本和格式等信息,能够拿到或修改这些信息

    3.结合上述1,2两点,表示了POI存在修改word文本并保留格式的可能,通过编写Demo修改了XWPFDocument中的一个XWPFParagraph对象中的XWPFRun文本内容后证明了这一点.

    XWPFDocument docx = new XWPFDocument(InputStream);
    XWPFRun run = docx.getParagraphs().get(0).getRuns().get(0);
    run.setText("modify");
    docx.write(OutputStream);

    六: 实现原理
    1.文本内容和表格内容分别可以通过 getParagraphs() 和 getTables() 两个方法得到

    XWPFDocument docx = new XWPFDocument(InputStream);
    //文本内容
    List<XWPFParagraph> allXWPFParagraphs = docx.getParagraphs();
    //表格内容
    List<XWPFTable> xwpfTables = docx.getTables();

    2.查看XWPFTable发现,最后表格中的文本内容还是用XWPFParagraph对象存储

    //获得每行
        List<XWPFTableRow> xwpfTableRows = = xwpfTable.getRows();
        List<XWPFTableCell> xwpfTableCells = new ArrayList<XWPFTableCell>();
        for(int i = 0 ; i < xwpfTableRows.size() ; i++){
                //获得一行的所有单元
            xwpfTableCells.addAll(getCells(i));
        }
        List<XWPFParagraph> xwpfParagraphs = new ArrayList<XWPFParagraph>();
        for(XWPFTableCell cell : xwpfTableCells){
                //获得每个单元中的文本
            xwpfParagraphs.addAll(cell.getParagraphs());
        }

    因此很可能最后修改表格和文本最后都汇集到一个相同的地方,就是修改XWPFParagraph的文本内容.进过简单的测试,证明了无论是表格还是文本,其内容都可以通过XWPFParagraph进行修改.

    3.研究XWPFParagraph中的内容发现,每个XWPFParagraph对象中存储的都是一整段的内容,而这一整段的内容被分割成多个部分存入了XWPFParagraph对象中的集合List runs,也许因为docx文件转换成xml的时候很大几率的会将相同格式的文本分割开来,所以每个XWPFRun展示的内容都是不连续的!!而这正是实现word模板的难点所在.

    4.因为没打算再深入研究docx转xml的原理,因此打算在现有的不连续的基础上进行封装,将其组合起来,模拟成”连续”的对象,最后对”连续”的对象进行replace操作.我的实现方法如下
    (1)获得完整的文本内容,用于判断是否包含${key}
    (2)对文本内容的每个字符标记所属的XWPFRun对象
    (3)如果匹配,则从标记中获取匹配的第一个字符,得到字符对应的标记对象,将替换的内容全部标记为该对象
    (4)替换完成后,遍历所有的标记,将标记对象所属的字符重新组合成String后重新设置,并将无用的标记对象文本设置为空

    public class XWPFParagraphUtils {
    
        private XWPFParagraph paragraph;
    
        private List<XWPFRun> allXWPFRuns;
        //所有run的String合并后的内容
        private StringBuffer context ;
        //长度与context对应的RunChar集合
        List<RunChar> runChars ;
    
        public XWPFParagraphUtils(XWPFParagraph paragraph){
            this.paragraph = paragraph;
            initParameter();
        }
    
        /**
         * 初始化各参数
         */
        private void initParameter(){
            context = new StringBuffer();
            runChars = new ArrayList<XWPFParagraphUtils.RunChar>();
            allXWPFRuns = new ArrayList<XWPFRun>();
            setXWPFRun();
        }
    
    
        /**
         * 设置XWPFRun相关的参数
         * @param run
         * @throws Exception
         */
        private void setXWPFRun() {
    
            allXWPFRuns = paragraph.getRuns();
            if(allXWPFRuns == null || allXWPFRuns.size() == 0){
                return;
            }else{
                for (XWPFRun run : allXWPFRuns) {
                    int testPosition = run.getTextPosition();
                    String text = run.getText(testPosition);
                    if(text == null || text.length() == 0){
                        return;
                    }
    
                    this.context.append(text);
                    for(int i = 0 ; i < text.length() ; i++){
                        runChars.add(new RunChar(text.charAt(i), run));
                    }
                }
            }
            System.out.println(context.toString());
        }
    
        public String getString(){
            return context.toString();
        }
    
        public boolean contains(String key){
            return context.indexOf(key) >= 0 ? true : false;
        }
    
        /**
         * 所有匹配的值替换为对应的值
         * @param key(匹配模板中的${key})
         * @param value 替换后的值
         * @return
         */
        public boolean replaceAll(String key,String value){
            boolean replaceSuccess = false;
            key = "${" + key + "}";
            while(replace(key, value)){
                replaceSuccess = true;
            }
            return replaceSuccess;
        }
    
        /**
         * 所有匹配的值替换为对应的值(key匹配模板中的${key})
         * @param param 要替换的key-value集合
         * @return
         */
        public boolean replaceAll(Map<String,String> param){
            Set<Entry<String, String>> entrys = param.entrySet();
            boolean replaceSuccess = false;
            for (Entry<String, String> entry : entrys) {
                String key = entry.getKey();
                boolean currSuccessReplace = replaceAll(key,entry.getValue());
                replaceSuccess = replaceSuccess?replaceSuccess:currSuccessReplace;
            }
            return replaceSuccess;
        }
    
        /**
         * 将第一个匹配到的值替換为对应的值
         * @param key 
         * @param value
         * @return
         */
        private boolean replace(String key,String value){
            if(contains(key)){
                /*
                 * 1:得带key对应的开始和结束下标
                 */
                int startIndex = context.indexOf(key);
                int endIndex = startIndex+key.length();
                /*
                 * 2:获取第一个匹配的XWPFRun
                 */
                RunChar startRunChar = runChars.get(startIndex);
                XWPFRun startRun = startRunChar.getRun();
                /*
                 * 3:将匹配的key清空
                 */
                runChars.subList(startIndex, endIndex).clear();
                /*
                 * 4:将value设置到startRun中
                 */
                List<RunChar> addRunChar = new ArrayList<XWPFParagraphUtils.RunChar>();
                for(int i = 0 ; i < value.length() ; i++){
                    addRunChar.add(new RunChar(value.charAt(i), startRun));
                }
                runChars.addAll(startIndex, addRunChar);
                resetRunContext(runChars);
                return true;
            }else{
                return false;
            }
        }
    
        private void resetRunContext(List<RunChar> newRunChars){
            /**
             * 生成新的XWPFRun与Context的对应关系
             */
            HashMap<XWPFRun, StringBuffer> newRunContext = new HashMap<XWPFRun, StringBuffer>();
            //重设context
            context = new StringBuffer();
            for(RunChar runChar : newRunChars){
                StringBuffer newRunText ;
                if(newRunContext.containsKey(runChar.getRun())){
                    newRunText = newRunContext.get(runChar.getRun());
                }else{
                    newRunText = new StringBuffer();
                }
                context.append(runChar.getValue());
                newRunText.append(runChar.getValue());
                newRunContext.put(runChar.getRun(), newRunText);
            }
    
            /**
             * 遍历旧的runContext,替换context
             * 并重新设置run的text,如果不匹配,text设置为""
             */
            for(XWPFRun run : allXWPFRuns){
                if(newRunContext.containsKey(run)){
                    String newContext = newRunContext.get(run).toString();
                    XWPFRunUtils.setText(run,newContext);
                }else{
                    XWPFRunUtils.setText(run,"");
                }
            }
        }
    
        /**
         * 实体类:存储字节与XWPFRun对象的对应关系
         * @author JianQiu
         */
        class RunChar{
            /**
             * 字节
             */
            private char value;
            /**
             * 对应的XWPFRun
             */
            private XWPFRun run;
            public RunChar(char value,XWPFRun run){
                this.setValue(value);
                this.setRun(run);
            }
            public char getValue() {
                return value;
            }
            public void setValue(char value) {
                this.value = value;
            }
            public XWPFRun getRun() {
                return run;
            }
            public void setRun(XWPFRun run) {
                this.run = run;
            }
    
        }
    }

    5.最后只需调用XWPFDocument.write(OutputStream)方法即可得到基于模板生成的docx文件了.

    七:小结
    完整的代码我已上传到GitHub,里面包含了说明以及测试用例,可以作为参考.
    https://github.com/DeveloperHuang/WordHandler
    目前只是简单的实现了替换的功能,后续功能可能下半年才有空研究了.

    展开全文
  • 从pdf文档中复制一部分内容word的时候,pdf的自动换行会自动让文字另起一行,这样粘贴到word中的时候也会有很多换行符 解决: ①Ctrl+H打开替换对话框,或点击Word工具栏中的查找和替换 ②在查找内容栏中输入^p...

    使用Word批量删除换行和空白行

    问题一:
    从pdf文档中复制一部分内容到word的时候,pdf的自动换行会自动让文字另起一行,这样粘贴到word中的时候也会有很多换行符

    解决:
    ①Ctrl+H打开替换对话框,或点击Word工具栏中的查找和替换
    ②在查找内容栏中输入^p(代表换行符),在替换栏中什么也不输入,点击全部替换即可

    问题二:
    删除Word文字间多余的空白行,即保留有文字的换行,删除没有文字的空白行,而不是删除所有的换行符

    解决:
    ①Ctrl+H打开替换对话框,或点击Word工具栏中的查找和替换
    ②在查找内容栏中输入pp(代表换行符),在替换栏中输入^p,点击全部替换即可

    展开全文
  • word中批量删除空格或空白区域在查找内容后面的文本框按一下空格键或者输入“^m”,替换内容部分留空,点全部替换即可。word中批量删除空行段落与段落之间留有太多空行了,只想保留一行该怎么办?这个可以通过Word的...

    Word批量打印、取消超链接及批量删除图片

    批量删除Word中的图片
    查找内容“^g”,替换内容留空,点击“全部替换”按钮即可把图片全部删除。

    word中批量删除空格或空白区域
    在查找内容后面的文本框按一下空格键或者输入“^m”,替换内容部分留空,点全部替换即可。

    word中批量删除空行
    段落与段落之间留有太多空行了,只想保留一行该怎么办?这个可以通过Word的宏操作实现,但略显麻烦,简单方法为:
    对于一般的硬回车,也就是段落标记,批量删除的方法是查找“^p^p”,将其全部替换为“^p”即可。;对于由Shift+Enter 键产生的软回车,也就是手动换行符(标记是向下的箭头),删除的方法是查找内容为“^l^l”,替换为“^l”。

    word批量取消超链接
    要批量删除Word中的链接,可以先Ctrl+A组合键全选,然后再按Ctrl+Shift+F9组合键即可取消文档中的所有链接。

    批量打印word文档
    如果有很多个Word文档需要打印,一个一个地打开文档再打印确实很费时。在手头上没有Word批量打印工具的前提下,下面的方法是我认为最快最便捷的批量打印word的方法:
    先将所有需要打印的word文档放在同一个文件夹下面,然后选择所有文件,点鼠标右键,选择“打印”即可。这时你会看到,每打印一个文档,Word会自动打开然后关闭,免去了手动的麻烦。

    转载于:https://www.cnblogs.com/gismemory/archive/2012/04/09/2438581.html

    展开全文
  • 虽然现在有一部分软件提供清除干扰码的功能,但还需要安装,并且只支持部分浏览器。其实不用那么麻烦,利用常用的Word 2007,就可以清除网页中的乱码。  首先打开Word 2007,然后粘贴要进行复制的文字。不要...

      相信大家在访问一些网站,复制网站信息的时候,会发现复制的内容里面包含乱码。这是网站为了保护版权,从而加上的干扰码!通常情况下需要手动将干扰码清除才可以,比较麻烦。虽然现在有一部分软件提供清除干扰码的功能,但还需要安装,并且只支持部分浏览器。其实不用那么麻烦,利用常用的Word 2007,就可以清除网页中的乱码。

      首先打开Word 2007,然后粘贴要进行复制的文字。不要清除格式,保留原来的格式。下面进入“开始-编辑-替换”,点击“更多”按钮,然后将光标定位到“查找内容选项”后的文本框中,再选择最下方“替换”一栏中的“格式/字体”。

       在字体颜色设置中选择白色,其它设置保持默认,“确定”后回到替换窗口,单击“全部替换”。
      
      经过上面的操作,就能够将网页中的干扰码去掉,只保留文本文件。这样做的原理是网页中的干扰码都是白色,而在Word 2007中的替换设置中将白色的字体去掉,就能够将干扰码进行删除。

      以后再在网上遇到干扰码,不用担心无法清除掉。利用Word 2007就可以轻松的去掉,节省了很多时间,也提高了工作效率。

     

     

    展开全文
  • 系统界面与Word 等Office产品紧密集成,可直接从Word里拖动一块内容到SSCMS中来。用户也可以在SSCMS里直接进行文字的排版处理, 比如改变字体名称,字体大小,字体颜色,背景颜色,以及对齐样式等等。还可以透明...
  • 1.强大的针对文本文档全文内容的批量字符或内容替换操作功能(跟Word替换功能一样) 2.针对文本文档内容中每一行内容的特殊删除、特殊添加、统计分割功能 3.提取文本文档内容中的指定的行作为文本文件新文件名的...
  • 1.强大的针对文本文档全文内容的批量字符或内容替换操作功能(跟Word替换功能一样) 2.针对文本文档内容中每一行内容的特殊删除、特殊添加、统计分割功能 3.提取文本文档内容中的指定的行作为文本文件新文件名的功能...
  • 2004-2010软考程序员真题

    热门讨论 2012-09-27 12:33:00
     62、在微型计算机内存储器中,不能用指令修改其存储内容部分是  A)RAM B)DRAM C)ROM D)SRAM  63、下列四条叙述中,正确的一条是  A)假若CPU向外输出20位地址,则它能直接访问的存储空间可达1MB  B)PC机在...
  • 交警电子笔录 1.61

    2011-11-17 12:53:17
     10、“笔录内容窗口”中,可以进行删除(删除一行)、剪切、复制、粘贴、查找与替换、关键字高亮显示(在笔录窗口中按F3键或CTRL+F组合键)、全选、撤销等操作,双击该窗口可以使内容还原为 默认格式;  11、在使用...
  • PowerPoint.2007宝典 8/10

    2012-04-01 18:39:23
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 10/10

    2012-04-01 18:45:00
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 9/10

    2012-04-01 18:42:38
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 7/10

    2012-04-01 18:36:57
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 6/10

    2012-04-01 18:34:41
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 5/10

    2012-04-01 18:32:23
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 4/10

    2012-04-01 18:30:04
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 3/10

    2012-04-01 18:27:45
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 2/10

    2012-04-01 18:25:11
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • PowerPoint.2007宝典 1/10

    2012-04-01 18:21:50
    第2部分 使用图形和多媒体内容 第10章 绘制对象并设置其格式 189 10.1 使用绘图工具 189 10.1.1 关于矢量图形 189 10.1.2 绘制线条和形状 190 10.1.3 选择不同的形状 193 10.1.4 编辑形状的顶点 194 ...
  • 5) 将粘贴功能区分为粘贴内容、粘贴文本、粘贴WORD三种功能。 6) 翻译了插入超链接功能里的打开方式说明。 7) 更新了部分的菜单功能图标。 <br>2007/7/26 Version 3.2.4 Free <br>Updates: 1)...
  • 【选区背景】 默认启动智能着色方式,此功能会清除一部分背景颜色,但对工作表中的条件格式会作完全保留,丝毫没有影响。最大的特点是支持屏幕行列捲轴的操作而不影响显示。 【选区背景选择】 进行着色功能切换,...
  • (1)修改中断禁止部分 # if defined(CONFIG_S3C2410) ldr r1, =0x7ff /*根据 2410 芯片手册,INTSUBMSK 有 11位可用 */ ldr r0, =INTSUBMSK Create PDF files without this message by purchasing novaPDF ...
  • 第三周,本github的部分Contributors 把全部文章从github转到word上,这部分contributors 包括包括:zhou1989、qiwsir、DogK、x140yu、ericxk、zhanglin0129、idouba.net、gaohua、kelvinkuo等; 第四周,继续在Word...
  • 华西网源码

    2014-07-06 13:15:47
    +----------------------------------+ 网站首页安装方法 +----------------------------------+ 1. 进入[系统设置]-[全局]-[站点功能],... 7)论坛内容页相关帖子条数请在后台 界面-界面设置-帖子内容页修改为6条 ...
  • 【选区背景】 默认启动智能着色方式,此功能会清除一部分背景颜色,但对工作表中的条件格式会作完全保留,丝毫没有影响。最大的特点是支持屏幕行列捲轴的操作而不影响显示。 【选区背景选择】 进行着色功能切换,...
  • EXCEL集成工具箱V6.0

    2010-09-11 01:44:37
    完 美 背 景 着 色 【选区背景】 默认启动智能着色方式,此功能会清除一部分背景颜色,但对工作表中的条件格式会作完全保留,丝毫没有影响。最大的特点是支持屏幕行列捲轴的操作而不影响显示。 【选区背景选择】 ...
  • 完 美 背 景 着 色 【选区背景】 默认启动智能着色方式,此功能会清除一部分背景颜色,但对工作表中的条件格式会作完全保留,丝毫没有影响。最大的特点是支持屏幕行列捲轴的操作而不影响显示。 【选区背景选择】 ...
  • 第3篇为协同工作篇,介绍如何实现Excel与Access、Word、文本格式的数据以及网站数据的共享。 目录: chapter 01 快速输入与编辑数据 1.1 文字的输入 1.1.1 在编辑栏中输入 1.1.2 在单元格中输入 1.1.3 文字的...
  •  拼写检查:在您输入代码的同时进行检查,并且可以看到同Microsoft Word相似的红色下划线。含有Spell check comments and strings,另外,Spell check code可以检查错误的输入符号。  拓展了基本编辑:对编辑器...

空空如也

空空如也

1 2 3 4 5
收藏数 99
精华内容 39
关键字:

word替换保留部分内容