前后端渲染,梦境与打梦机
分类:技术

 4、梦境是超现实主义画派崛起的摇篮

3.精读

大家对前端和后端渲染的现状基本达成共识。即前端渲染是未来趋势,但前端渲染遇到了首屏性能和SEO的问题。对于同构争议最多。在此我归纳一下。

前端渲染主要面临的问题有两个 SEO、首屏性能。

SEO 很好理解。由于传统的搜索引擎只会从 HTML 中抓取数据,导致前端渲染的页面无法被抓取。前端渲染常使用的 SPA 会把所有 JS 整体打包,无法忽视的问题就是文件太大,导致渲染前等待很长时间。特别是网速差的时候,让用户等待白屏结束并非一个很好的体验。

现在说一下程序处理部分,有点长

    第一类:学生时代的经历。试想,我们每个人从小学、初中,到高中、大学,包括参加工作以后,都会面临各种各样的考试,有谁不担心考试不过关呢?尤其是一锤定音的高考,更是让人捏把汗。所以,才会经常梦到担心考试的事。在外地读书,面对远离家乡的思念和对放假的期待,谁又不想顺顺利利、早点回到家呢?这些隐藏在心底的思乡情结,也是我们经常做学生时代的愁苦梦的主要原因。除了小学在村里读书外,我从小一直在外地上学。上初中时,离家2公里,要步行近半小时;上高中时,离家60多公里,骑自行车要3个小时。雨雪天是最担心的,相信大家都可以想象到顶风冒雨骑自行车的感受;上大学时,离家2200公里,火车硬座要坐37个小时。这还不包括中转等车的时间,中间如果没有办到当天的火车中转鉴字手续,时间还要延后一天。从车窗钻进车厢里、中途无座票、连续站十几个小时的日子并非没遇到过。想想,那时候的交通可真不方便。现在坐飞机3小时就到达,那时候要好几天,带着行李拥挤和折腾的经历是让人终生难忘的。因此,既便过了许多年,我们梦里仍会经常出现坐火车买不到票、行里太多拿不走、好不容易挤上车却弄丢东西等现象。其实,这都是现实境遇在潜意识里的一种反映。

2.内容概要

                2. word中嵌入的Excel图表的问题, 虽然生成结果中的图表数据是正确的, 但无法右键再次编辑数据, 只可修改样式.

    2、梦境可以给诗人插上灵感的翅膀。

同构并没有想像中那么美
  1. 性能
    把原来放在几百万浏览器端的工作拿过来给你几台服务器做,这还是花挺多计算力的。尤其是涉及到图表类需要大量计算的场景。这方面调优,可以参考walmart的调优策略。

个性化的缓存是遇到的另外一个问题。可以把每个用户个性化信息缓存到浏览器,这是一个天生的分布式缓存系统。我们有个数据类应用通过在浏览器合理设置缓存,双十一当天节省了 70% 的请求量。试想如果这些缓存全部放到服务器存储,需要的存储空间和计算都是很非常大。

  1. 不容忽视的服务器端和浏览器环境差异
    前端代码在编写时并没有过多的考虑后端渲染的情景,因此各种 BOM 对象和 DOM API 都是拿来即用。这从客观层面也增加了同构渲染的难度。我们主要遇到了以下几个问题:
    •document 等对象找不到的问题
    •DOM 计算报错的问题
    •前端渲染和服务端渲染内容不一致的问题

由于前端代码使用的 window 在 node 环境是不存在的,所以要 mock window,其中最重要的是 cookie,userAgent,location。但是由于每个用户访问时是不一样的 window,那么就意味着你得每次都更新 window。
而服务端由于 js require 的 cache 机制,造成前端代码除了具体渲染部分都只会加载一遍。这时候 window 就得不到更新了。所以要引入一个合适的更新机制,比如把读取改成每次用的时候再读取。

export const isSsr = () => (
  !(typeof window !== 'undefined' && window.document && window.document.createElement && window.setTimeout)
);

原因是很多 DOM 计算在 SSR 的时候是无法进行的,涉及到 DOM 计算的的内容不可能做到 SSR 和 CSR 完全一致,这种不一致可能会带来页面的闪动。

  1. 内存溢出
    前端代码由于浏览器环境刷新一遍内存重置的天然优势,对内存溢出的风险并没有考虑充分。
    比如在 React 的 componentWillMount 里做绑定事件就会发生内存溢出,因为 React 的设计是后端渲染只会运行 componentDidMount 之前的操作,而不会运行 componentWillUnmount 方法(一般解绑事件在这里)。

  2. 异步操作
    前端可以做非常复杂的请求合并和延迟处理,但为了同构,所有这些请求都在预先拿到结果才会渲染。而往往这些请求是有很多依赖条件的,很难调和。纯 React 的方式会把这些数据以埋点的方式打到页面上,前端不再发请求,但仍然再渲染一遍来比对数据。造成的结果是流程复杂,大规模使用成本高。幸运的是 Next.js 解决了这一些,后面会谈到。

  3. simple store(redux)
    这个 store 是必须以字符串形式塞到前端,所以复杂类型是无法转义成字符串的,比如function。

总的来说,同构渲染实施难度大,不够优雅,无论在前端还是服务端,都需要额外改造。

后续问题: 1.部署: 目前我的开发环境里装的是office2016 的office365版 引用的是  Microsoft Word 16.0 Object Library, 对应的Microsoft.Office.Interop.Word.dll版本是15.0...  

    我醒了,发现自己刚才在梦中。

总结

我们赞成客户端渲染是未来的主要方向,服务端则会专注于在数据和业务处理上的优势。但由于日趋复杂的软硬件环境和用户体验更高的追求,也不能只拘泥于完全的客户端渲染。同构渲染看似美好,但以目前的发展程度来看,在大型项目中还不具有足够的应用价值,但不妨碍部分使用来优化首屏性能。做同构之前 ,一定要考虑到浏览器和服务器的环境差异,站在更高层面考虑。

C# 处理Word自动生成报告 四、程序处理

    三是关于儿时的趣事。当然,并非所有的梦都是不快活的,让人心怡的美妙境界也有,只是它们占的比例很小。记得小时候,经常梦到自己可以在天空中飞翔,双腿并拢,双臂平举,只要仰头吸气,就可上升;低头呼气,就可平飞;收拢划动胳膊,身体就能完成转向。自家的院子、邻家的柴垛、学校的小树林、碧绿的田野,全部尽收眼底。心驶驭了身体,心里想去哪儿,身子就可以转向飞到哪。多么美妙的感觉呀,简直就是一只身轻如燕的自由鸟!对于这样的梦,我又问了奶奶,她说,“梦到在天上飞,说明你在长身体。梦到从高处摔下、或者掉到深渊里,就要小心,别有什么灾难出现”。为此,奶奶还在佛堂前上了几柱香,以求避灾与宽慰,好在我只有那么一次梦到过从高处坠落。此外,还有一个乐此不彼的美梦是捡硬币。我家门口有一条平坦湿润的泥土小路,不知谁丢下许多硬币,全部是面值5分钱。它们太多了,好像有人故意放好似的,呈一条曲线一枚一枚地排列着,延伸到很远的地方。不一会儿,上衣和裤兜就装不下了。后来,干脆回家取了个大麻袋来,并叫上弟弟和妹妹来帮忙,专挑那些崭新的捡,带泥发脏的全不要。等硬币快装满的时候,我们三个孩子才发现,根本拖不动沉重的麻袋……

前端渲染的优势:

  1. 局部刷新。无需每次都进行完整页面请求
  2. 懒加载。如在页面初始时只加载可视区域内的数据,滚动后rp加载其它数据,可以通过 react-lazyload 实现
  3. 富交互。使用 JS 实现各种酷炫效果
  4. 节约服务器成本。省电省钱,JS 支持 CDN 部署,且部署极其简单,只需要服务器支持静态文件即可
  5. 天生的关注分离设计。服务器来访问数据库提供接口,JS 只关注数据获取和展现
  6. JS 一次学习,到处使用。可以用来开发 Web、Serve、Mobile、Desktop 类型的应用

C# 处理Word自动生成报告 一、概述

    第三类:儿时的趣事,同样蕴含了一种对家乡和亲人的惦念之情,还有对急于脱贫的渴望。梦到捡硬币,虽然金额小的不足挂齿,但反映了我们从孩提时代就希望变的富有、能过上好日子的愿望。这也许是生于60-70年代的人共有的特征。现实里无法做到,只能在梦里满足这个欲望,不是吗?小时候,奶奶对我被狗咬蛇追等恶梦的解释,总是用“将来会发财、长大了不会受穷”等字眼来安慰,这难道不也代表了当时社会共有的一种追求和向往吗?

前后端渲染之争

                  ReadOnly: false的情况下, office2016  office2013均测试通过.

    如果你对这个哲学命题仍然感到困惑不解,觉得太烧脑伤神,这很正常,因为我们不是哲学家。暂且把它当作一个梦境能引发哲学思考的例子看待吧。

首屏优化

再回到前端渲染遇到首屏渲染问题,除了同构就没有其它解法了吗?总结以下可以通过以下三步解决

  1. 分拆打包
    现在流行的路由库如 react-router 对分拆打包都有很好的支持。可以按照页面对包进行分拆,并在页面切换时加上一些 loading 和 transition 效果。

  2. 交互优化
    首次渲染的问题可以用更好的交互来解决,先看下 linkedin 的渲染

有什么感受,非常自然,打开渲染并没有白屏,有两段加载动画,第一段像是加载资源,第二段是一个加载占位器,过去我们会用 loading 效果,但过渡性不好。近年流行 Skeleton Screen 效果。其实就是在白屏无法避免的时候,为了解决等待加载过程中白屏或者界面闪烁造成的割裂感带来的解决方案。

  1. 部分同构
    部分同构可以降低成功同时利用同构的优点,如把核心的部分如菜单通过同构的方式优先渲染出来。我们现在的做法就是使用同构把菜单和页面骨架渲染出来。给用户提示信息,减少无端的等待时间。

相信有了以上三步之后,首屏问题已经能有很大改观。相对来说体验提升和同构不分伯仲,而且相对来说对原来架构破坏性小,入侵性小。是我比较推崇的方案。

 

    既然无处可逃,不如喜悦。

1.引言

十年前,几乎所有网站都使用 ASP、Java、PHP 这类做后端渲染,但后来随着 jQuery、Angular、React、Vue 等 JS 框架的崛起,开始转向了前端渲染。从 2014 年起又开始流行了同构渲染,号称是未来,集成了前后端渲染的优点,但转眼间三年过去了,很多当时壮心满满的框架(Rendlr、Lazo)从先驱变成了先烈。同构到底是不是未来?自己的项目该如何选型?我想不应该只停留在追求热门和拘泥于固定模式上,忽略了前后端渲染之“争”的“核心点”,关注如何提升“用户体验”。

主要分析前端渲染的优势,并没有进行深入探讨。我想通过它为切入口来深入探讨一下。
明确三个概念:

  1. 「后端渲染」指传统的 ASP、Java 或 PHP 的渲染机制;
  2. 「前端渲染」指使用 JS 来渲染页面大部分内容,代表是现在流行的 SPA 单页面应用;
  3. 「同构渲染」指前后端共用 JS,首次渲染时使用 Node.js 来直出 HTML。一般来说同构渲染是介于前后端中的共有部分。

想要doc的情况可以选择生成格式为doc的.

    顷刻,捕鱼队伍从海边归村,身后拖着长长的丝网,网内鱼儿活蹦乱跳。突然,我似乎再次想起当初进村的渔船,于是急忙跑到村东的海边,想坐船回家。但那里只有大海,没有渔船;只有潋滟波光,没有离村的通道。倏尔,天空变了色,金、蓝、绿、粉、青、紫,五光十色;鱼鳞云,片片叠盖;似孔雀之尾,覆满远天空;层云与倒影相接,水天一线,辉映迷幻;斑斓境让人沉醉,不知归去。

同构的优点:

同构恰恰就是为了解决前端渲染遇到的问题才产生的,至 2014 年底伴随着 React 的崛起而被认为是前端框架应具备的一大杀器,以至于当时很多人为了用此特性而 放弃 Angular 1 而转向 React。然而近3年过去了,很多产品逐渐从全栈同构的理想化逐渐转到首屏或部分同构。让我们再一次思考同构的优点真是优点吗?

  1. 有助于 SEO
    • 首先确定你的应用是否都要做 SEO,如果是一个后台应用,那么只要首页做一些静态内容宣导就可以了。如果是内容型的网站,那么可以考虑专门做一些页面给搜索引擎
    •时到今日,谷歌已经能够可以在爬虫中执行 JS 像浏览器一样理解网页内容,只需要往常一样使用 JS 和 CSS 即可。并且尽量使用新规范,使用 pushstate 来替代以前的 hashstate。不同的搜索引擎的爬虫还不一样,要做一些配置的工作,而且可能要经常关注数据,有波动那么可能就需要更新。第二是该做 sitemap 的还得做。相信未来即使是纯前端渲染的页面,爬虫也能很好的解析。

  2. 共用前端代码,节省开发时间
    其实同构并没有节省前端的开发量,只是把一部分前端代码拿到服务端执行。而且为了同构还要处处兼容 Node.js 不同的执行环境。有额外成本,这也是后面会具体谈到的。

  3. 提高首屏性能
    由于 SPA 打包生成的 JS 往往都比较大,会导致页面加载后花费很长的时间来解析,也就造成了白屏问题。服务端渲染可以预先使到数据并渲染成最终 HTML 直接展示,理想情况下能避免白屏问题。在我参考过的一些产品中,很多页面需要获取十几个接口的数据,单是数据获取的时候都会花费数秒钟,这样全部使用同构反而会变慢。

C# 处理Word自动生成报告 二、数据源例子

    前面描述的三类梦,别人是不是也有?曾经咨询过不少朋友,大部分同龄人也做过这类梦,尤其是考试的梦几乎人人皆有。此外,他们还会经常梦到什么内容?大多数表示为,还会梦到与工作、生活、亲人有关的事情。比如梦到去世多年的亲人,甚至会梦到健在的父母突然去逝,这是多么不应该发生的梦啊,可它偏偏出现了!这种与现实相反的梦是不是潜意识执行了上帝安排的任务,来提醒我们要珍惜亲人、乘父母还健在的时候多尽孝心呢?工作上的事出现在梦中也是常有的。有人坦承,他们通过带有情节和思考的梦(似睡似醒的梦境),竟然把工作和家庭中遇到的困难问题解决了,梦帮了我们。这一点正好契合了“梦是大脑在虚拟环境中对如何处置危险情况的预演”这个观点。从好坏比例上看,恶梦总是多于美梦,被吓醒的都是恶梦。但不论怎样,二者的根都是我们的生活经历(尤其是童年经历)、潜意识里隐藏的感情,梦把它们折射和重现了出来。

后端渲染的优势:

  1. 服务端渲染不需要先下载一堆 js 和 css 后才能看到页面(首屏性能)
  2. SEO
  3. 服务端渲染不用关心浏览器兼容性问题(随意浏览器发展,这个优点逐渐消失)
  4. 对于电量不给力的手机或平板,减少在客户端的电量消耗很重要

以上服务端优势其实只有首屏性能和 SEO 两点比较突出。但现在这两点也慢慢变得微不足道了。React 这类支持同构的框架已经能解决这个问题,尤其是 Next.js 让同构开发变得非常容易。还有静态站点的渲染,但这类应用本身复杂度低,很多前端框架已经能完全囊括。

所以此版只支持对docx的模板处理,

  3、梦境是活跃于音乐海洋的音符。

 public class WordHelper
    {
        private Word.Application wordApp = null;
        private Word.Document wordDoc = null;
        private DataSet dataSource = null;
        private object line = Word.WdUnits.wdLine;
        private string errorMsg = "";

        /// <summary>
        /// 根据模板文件,创建数据报告
        /// </summary>
        /// <param name="templateFile">模板文件名(含路径)</param>
        /// <param name="newFilePath">新文件路径)</param>
        /// <param name="dataSource">数据源,包含多个datatable</param>
        /// <param name="saveFormat">新文件格式:</param>
        public bool CreateReport(string templateFile, DataSet dataSource, out string errorMsg, string newFilePath, ref string newFileName, int saveFormat = 16)
        {
            this.dataSource = dataSource;
            errorMsg = this.errorMsg;
            bool rtn = OpenTemplate(templateFile)
                && SetContent(new WordElement(wordDoc.Range(), dataRow: dataSource.Tables[dataSource.Tables.Count - 1].Rows[0]))
                && UpdateTablesOfContents()
                && SaveFile(newFilePath, ref newFileName, saveFormat);

            CloseAndClear();
            return rtn;
        }
        private bool OpenTemplate(string templateFile)
        {
            if (!File.Exists(templateFile))
            {
                return false;
            }

            wordApp = new Word.ApplicationClass();
            wordApp.Visible = false;//使文档可见,调试用
            wordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
            object file = templateFile;
            wordDoc = wordApp.Documents.Open(ref file, ReadOnly: true);
            return true;
        }

        private bool SetContent(WordElement element)
        {
            string currBookMarkName = string.Empty;
            string startWith = "loop_" + (element.Level + 1).ToString() + "_";
            foreach (Word.Bookmark item in element.Range.Bookmarks)
            {
                currBookMarkName = item.Name;

                if (currBookMarkName.StartsWith(startWith) && (!currBookMarkName.Equals(element.ElementName)))
                {
                    SetLoop(new WordElement(item.Range, currBookMarkName, element.DataRow, element.GroupBy));
                }

            }

            SetLabel(element);

            SetTable(element);

            SetChart(element);

            return true;
        }
        private bool SetLoop(WordElement element)
        {
            DataRow[] dataRows = dataSource.Tables[element.TableIndex].Select(element.GroupByString);
            int count = dataRows.Count();
            element.Range.Select();

            //第0行作为模板  先从1开始  循环后处理0行;
            for (int i = 0; i < count; i++)
            {

                element.Range.Copy();  //模板loop复制
                wordApp.Selection.InsertParagraphAfter();//换行 不会清除选中的内容,TypeParagraph 等同于回车,若当前有选中内容会被清除. TypeParagraph 会跳到下一行,InsertParagraphAfter不会, 所以movedown一下.
                wordApp.Selection.MoveDown(ref line, Missing.Value, Missing.Value);
                wordApp.Selection.Paste(); //换行后粘贴复制内容
                int offset = wordApp.Selection.Range.End - element.Range.End; //计算偏移量

                //复制书签,书签名 = 模板书签名 + 复制次数
                foreach (Word.Bookmark subBook in element.Range.Bookmarks)
                {
                    if (subBook.Name.Equals(element.ElementName))
                    {
                        continue;
                    }

                    wordApp.Selection.Bookmarks.Add(subBook.Name + "_" + i.ToString(), wordDoc.Range(subBook.Start + offset, subBook.End + offset));
                }

                SetContent(new WordElement(wordDoc.Range(wordApp.Selection.Range.End - (element.Range.End - element.Range.Start), wordApp.Selection.Range.End), element.ElementName + "_" + i.ToString(), dataRows[i], element.GroupBy));
            }

            element.Range.Delete();

            return true;
        }
        private bool SetLabel(WordElement element)
        {
            if (element.Range.Bookmarks != null && element.Range.Bookmarks.Count > 0)
            {
                string startWith = "label_" + element.Level.ToString() + "_";
                string bookMarkName = string.Empty;
                foreach (Word.Bookmark item in element.Range.Bookmarks)
                {
                    bookMarkName = item.Name;

                    if (bookMarkName.StartsWith(startWith))
                    {
                        bookMarkName = WordElement.GetName(bookMarkName);

                        item.Range.Text = element.DataRow[bookMarkName].ToString();
                    }
                }
            }

            return true;
        }
        private bool SetTable(WordElement element)
        {
            if (element.Range.Tables != null && element.Range.Tables.Count > 0)
            {
                string startWith = "table_" + element.Level.ToString() + "_";
                foreach (Word.Table table in element.Range.Tables)
                {
                    if (!string.IsNullOrEmpty(table.Title) && table.Title.StartsWith(startWith))
                    {
                        WordElement tableElement = new WordElement(null, table.Title, element.DataRow);

                        TableConfig config = new TableConfig(table.Descr);

                        object dataRowTemplate = table.Rows[config.DataRow];
                        Word.Row SummaryRow = null;
                        DataRow SummaryDataRow = null;
                        DataTable dt = dataSource.Tables[tableElement.TableIndex];
                        DataRow[] dataRows = dataSource.Tables[tableElement.TableIndex].Select(tableElement.GroupByString); ;

                        if (config.SummaryRow > 0)
                        {
                            SummaryRow = table.Rows[config.SummaryRow];
                            SummaryDataRow = dt.Select(string.IsNullOrEmpty(tableElement.GroupByString) ? config.SummaryFilter : tableElement.GroupByString + " and  " + config.SummaryFilter).FirstOrDefault();
                        }

                        foreach (DataRow row in dataRows)
                        {
                            if (row == SummaryDataRow)
                            {
                                continue;
                            }

                            Word.Row newRow = table.Rows.Add(ref dataRowTemplate);
                            for (int j = 0; j < table.Columns.Count; j++)
                            {
                                newRow.Cells[j + 1].Range.Text = row[j].ToString(); ;
                            }

                        }

                        ((Word.Row)dataRowTemplate).Delete();

                        if (config.SummaryRow > 0 && SummaryDataRow != null)
                        {
                            for (int j = 0; j < SummaryRow.Cells.Count; j++)
                            {
                                string temp = SummaryRow.Cells[j + 1].Range.Text.Trim().Replace("ra", "");

                                if (!string.IsNullOrEmpty(temp) && temp.Length > 2 && dt.Columns.Contains(temp.Substring(1, temp.Length - 2)))
                                {
                                    SummaryRow.Cells[j + 1].Range.Text = SummaryDataRow[temp.Substring(1, temp.Length - 2)].ToString();
                                }
                            }
                        }

                        table.Title = tableElement.Name;
                    }


                }
            }

            return true;
        }
        private bool SetChart(WordElement element)
        {
            if (element.Range.InlineShapes != null && element.Range.InlineShapes.Count > 0)
            {
                List<Word.InlineShape> chartList = element.Range.InlineShapes.Cast<Word.InlineShape>().Where(m => m.Type == Word.WdInlineShapeType.wdInlineShapeChart).ToList();
                string startWith = "chart_" + element.Level.ToString() + "_";
                foreach (Word.InlineShape item in chartList)
                {
                    Word.Chart chart = item.Chart;
                    if (!string.IsNullOrEmpty(chart.ChartTitle.Text) && chart.ChartTitle.Text.StartsWith(startWith))
                    {
                        WordElement chartElement = new WordElement(null, chart.ChartTitle.Text, element.DataRow);

                        DataTable dataTable = dataSource.Tables[chartElement.TableIndex];
                        DataRow[] dataRows = dataTable.Select(chartElement.GroupByString);

                        int columnCount = dataTable.Columns.Count;
                        List<int> columns = new List<int>();

                        foreach (var dr in dataRows)
                        {
                            for (int i = chartElement.ColumnStart == -1 ? 0 : chartElement.ColumnStart - 1; i < (chartElement.ColumnEnd == -1 ? columnCount : chartElement.ColumnEnd); i++)
                            {
                                if (columns.Contains(i) || dr[i] == null || string.IsNullOrEmpty(dr[i].ToString()))
                                {

                                }
                                else
                                {
                                    columns.Add(i);
                                }
                            }
                        }
                        columns.Sort();
                        columnCount = columns.Count;
                        int rowsCount = dataRows.Length;

                        Word.ChartData chartData = chart.ChartData;

                        //chartData.Activate();
                        //此处有个比较疑惑的问题, 不执行此条,生成的报告中的图表无法再次右键编辑数据. 执行后可以, 但有两个问题就是第一会弹出Excel框, 处理完后会自动关闭. 第二部分chart的数据range设置总不对
                        //不知道是不是版本的问题, 谁解决了分享一下,谢谢

                        Excel.Workbook dataWorkbook = (Excel.Workbook)chartData.Workbook;
                        dataWorkbook.Application.Visible = false;

                        Excel.Worksheet dataSheet = (Excel.Worksheet)dataWorkbook.Worksheets[1];
                        //设定范围  
                        string a = (chartElement.ColumnNameForHead ? rowsCount + 1 : rowsCount) + "|" + columnCount;
                        Console.WriteLine(a);

                        Excel.Range tRange = dataSheet.Range["A1", dataSheet.Cells[(chartElement.ColumnNameForHead ? rowsCount + 1 : rowsCount), columnCount]];
                        Excel.ListObject tbl1 = dataSheet.ListObjects[1];
                        //dataSheet.ListObjects[1].Delete(); //想过重新删除再添加  这样 原有数据清掉了, 但觉得性能应该会有所下降
                        //Excel.ListObject tbl1 = dataSheet.ListObjects.AddEx();
                        tbl1.Resize(tRange);
                        for (int j = 0; j < rowsCount; j++)
                        {
                            DataRow row = dataRows[j];
                            for (int k = 0; k < columnCount; k++)
                            {
                                dataSheet.Cells[j + 2, k + 1].FormulaR1C1 = row[columns[k]];
                            }
                        }

                        if (chartElement.ColumnNameForHead)
                        {
                            for (int k = 0; k < columns.Count; k++)
                            {
                                dataSheet.Cells[1, k + 1].FormulaR1C1 = dataTable.Columns[columns[k]].ColumnName;
                            }
                        }
                        chart.ChartTitle.Text = chartElement.Name;
                        //dataSheet.Application.Quit();
                    }
                }
            }

            return true;
        }
        private bool UpdateTablesOfContents()
        {
            foreach (Word.TableOfContents item in wordDoc.TablesOfContents)
            {
                item.Update();
            }

            return true;
        }
        private bool SaveFile(string newFilePath, ref string newFileName, int saveFormat = 16)
        {
            if (string.IsNullOrEmpty(newFileName))
            {
                newFileName = DateTime.Now.ToString("yyyyMMddHHmmss");

                switch (saveFormat)
                {
                    case 0:// Word.WdSaveFormat.wdFormatDocument
                        newFileName += ".doc";
                        break;
                    case 16:// Word.WdSaveFormat.wdFormatDocumentDefault
                        newFileName += ".docx";
                        break;
                    case 17:// Word.WdSaveFormat.wdFormatPDF
                        newFileName += ".pdf";
                        break;
                    default:
                        break;
                }
            }

            object newfile = Path.Combine(newFilePath, newFileName);
            object wdSaveFormat = saveFormat;
            wordDoc.SaveAs(ref newfile, ref wdSaveFormat);
            return true;
        }

        private void CloseAndClear()
        {
            if (wordApp == null)
            {
                return;
            }
            wordDoc.Close(Word.WdSaveOptions.wdDoNotSaveChanges);
            wordApp.Quit(Word.WdSaveOptions.wdDoNotSaveChanges);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(wordDoc);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp);
            wordDoc = null;
            wordApp = null;
            GC.Collect();
            KillProcess("Excel","WINWORD");
        }

        private void KillProcess(params string[] processNames)
        {
            //Process myproc = new Process();
            //得到所有打开的进程  
            try
            {
                foreach (string name in processNames)
                {
                    foreach (Process thisproc in Process.GetProcessesByName(name))
                    {
                        if (!thisproc.CloseMainWindow())
                        {
                            if (thisproc != null)
                                thisproc.Kill();
                        }
                    }
                }
            }
            catch (Exception)
            {
                //throw Exc;
                // msg.Text+=  "杀死"  +  processName  +  "失败!";  
            }
        }
    }

    public class WordElement
    {
        public WordElement(Word.Range range, string elementName = "", DataRow dataRow = null, Dictionary<string, string> groupBy = null, int tableIndex = 0)
        {
            this.Range = range;
            this.ElementName = elementName;
            this.GroupBy = groupBy;
            this.DataRow = dataRow;
            if (string.IsNullOrEmpty(elementName))
            {
                this.Level = 0;
                this.TableIndex = tableIndex;
                this.Name = string.Empty;
                this.ColumnNameForHead = false;
            }
            else
            {
                string[] element = elementName.Split('_');
                this.Level = int.Parse(element[1]);
                this.ColumnNameForHead = false;
                this.ColumnStart = -1;
                this.ColumnEnd = -1;

                if (element[0].Equals("label"))
                {
                    this.Name = element[2];
                    this.TableIndex = 0;
                }
                else
                {
                    this.Name = element[4];
                    this.TableIndex = int.Parse(element[2]) - 1;

                    if (!string.IsNullOrEmpty(element[3]))
                    {
                        string[] filters = element[3].Split(new string[] { "XX" }, StringSplitOptions.RemoveEmptyEntries);
                        if (this.GroupBy == null)
                        {
                            this.GroupBy = new Dictionary<string, string>();
                        }
                        foreach (string item in filters)
                        {
                            if (!this.GroupBy.Keys.Contains(item))
                            {
                                this.GroupBy.Add(item, dataRow[item].ToString());
                            }

                        }
                    }

                    if (element[0].Equals("chart") && element.Count() > 5)
                    {
                        this.ColumnNameForHead = element[5].Equals("1");
                        this.ColumnStart = string.IsNullOrEmpty(element[6]) ? -1 : int.Parse(element[6]);
                        this.ColumnEnd = string.IsNullOrEmpty(element[7]) ? -1 : int.Parse(element[7]);
                    }
                }
            }
        }

        public Word.Range Range { get; set; }
        public int Level { get; set; }
        public int TableIndex { get; set; }
        public string ElementName { get; set; }

        public DataRow DataRow { get; set; }
        public Dictionary<string, string> GroupBy { get; set; }

        public string Name { get; set; }

        public bool ColumnNameForHead { get; set; }
        public int ColumnStart { get; set; }
        public int ColumnEnd { get; set; }

        public string GroupByString
        {
            get
            {
                if (GroupBy == null || GroupBy.Count == 0)
                {
                    return string.Empty;
                }

                string rtn = string.Empty;
                foreach (string key in this.GroupBy.Keys)
                {
                    rtn += "and " + key + " = '" + GroupBy[key] + "' ";
                }
                return rtn.Substring(3);
            }
        }

        public static string GetName(string elementName)
        {
            string[] element = elementName.Split('_');


            if (element[0].Equals("label"))
            {
                return element[2];
            }
            else
            {
                return element[4];
            }
        }
    }

    public class TableConfig
    {
        public TableConfig(string tableDescr = "")
        {
            this.DataRow = 2;
            this.SummaryRow = -1;

            if (!string.IsNullOrEmpty(tableDescr))
            {
                string[] element = tableDescr.Split(',');
                foreach (string item in element)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        string[] configs = item.Split(':');
                        if (configs.Length == 2)
                        {
                            switch (configs[0].ToLower())
                            {
                                case "data":
                                case "d":
                                    this.DataRow = int.Parse(configs[1]);
                                    break;
                                case "summary":
                                case "s":
                                    this.SummaryRow = int.Parse(configs[1]);
                                    break;
                                case "summaryfilter":
                                case "sf":
                                    this.SummaryFilter = configs[1];
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
            }

        }
        public int DataRow { get; set; }
        public int SummaryRow { get; set; }
        public string SummaryFilter { get; set; }
    }

    最后,让我们以画家丰子恺的名言共勉,以结束此文。

上代码:

    小学放学回家,已接近傍晚,天雾濛濛的。因班级值日比较晚,我没能和同学们一起走,有点害怕。结果,刚走进离家不远的小道,看到前面突然冒出一只大狗来,它是挣脱狗链从邻居家的院子里冲出来的。这条狗实在是太大了,简直像一头小黄牛,直接向我这边扑来,真是吓人!

图片 1图片 2

    其实,梦境有几个特点:1、放大效应。恶梦总是比现实恐怖,美梦总是比现实幸福,这是由人类的恐惧天性和贪求心理决定的。现实当中对一件事的担忧害怕、缺乏底气与信心,往往经过潜意识的放大就会变成恶梦。2、怀旧情结。我们梦到童年时光的次数,总是要多于晚年经历的事情,因为人是善于回忆的,而童年又是人生中最美的一段时光。3、拟真性,再离奇古怪的梦都有现实的影子在里面。日有所思,夜有所想。这就是梦的起源。

                  发现office2013版本也是15, 只是小版本不同, 没找到office 2016 和2013的 primary interop assembly, 莫非部署的环境里也要安装完整的office?

  (小品文 高平)

                  为了避免文件占用问题,打开模板采用了只读方式打开wordDoc = wordApp.Documents.Open(ref file, ReadOnly: true);  在office2016(office365)版测试通过, 但专业版测试失败. 

  一个朋友欣喜地告诉我,他把很多特别的梦写在本子上,还配了画,多年以后看看它们,觉得很有趣。

C# 处理Word自动生成报告 三、设计模板

    在梦中,我来到了一个神奇而陌生的地方,它是大海上的一个世外桃花。那里,阳光明媚,东南的大海静如明台,细密的微波随轻风丝丝漾涌,海面浮有一个宁静的岛村。村南的庙宇肃穆庄严,面北依水,直升云宵。因背光而立,无法看清细节,雄壮秀美的剪影轮廓里似有观音之像,此景如烟似幻,此境令人暇思。

View Code

    循广场小路西行,忽见古街闹集。集市人来人往,南北木舍依街对望,古朴典雅,尺高不过三层。秋日午后,日光低泄,暖暖融融,街南建筑长影连片,此时已为半炙半凉之境,此景疑为《清明上河图》之繁喧。尝农家美食,品岛村风情,不觉间已近夕下时分,雁南飞,人欲归。

 

    贝多芬一生创作了大量名曲,但46岁时耳朵完全丧失听觉,他依然坚持创作。当他用双手奏响《命运交响曲》时,耳朵是什么也听不到的,他本人是一种什么感受呢?也许,我们可以这样猜想,那目光中所见的跳动的音符在这位大师眼里已失去意义,他在失听的世界里做着自己的音乐梦,他已融入并徜徉于他的梦境之中,那跳动的音符已然让他听到了梦境世界的波勇潮落。

希望有知道的看到给个回复.  打算有时间研究一下OpenXML, 希望能完美解决上面的问题.

    既然没有净土,不如静心。

本来是想做针对doc和docx的模板两个版本, 后来想到可以在生成的时候saveas里设置格式,

    最后,好心的渔翁拉了拉我的衣角,说:“离村的行船一周一班,今天已经收工,你要等到下周。”

                3. 性能问题: 处理速度较慢.

    “我欲因之梦吴越,一夜飞度镜湖月。湖月照我影,送我至剡溪。谢公宿处今尚在,渌水荡漾清猿啼。脚著谢公屐,身登青云梯。半壁见海日,空中闻天鸡。千岩万转路不定,迷花倚石忽已暝。熊咆龙吟殷岩泉,栗深林兮惊层巅。云青青兮欲雨,水澹澹兮生烟。列缺霹雳,丘峦崩摧。洞天石扉,訇然中开。青冥浩荡不见底,日月照耀金银台。霓为衣兮风为马,云之君兮纷纷而来下。虎鼓瑟兮鸾回车,仙之人兮列如麻。忽魂悸以魄动,恍惊起而长嗟,惟觉时之枕席,失向来之烟霞。”

    一是关于学生时代的内容。比如拿到考试卷一看,发现一道题也不会做,好像白学了一样,当时就懵了;要么就是突然发现忘记做试卷背面的题,而身边的同学马上要交卷了,连抄都来不及,真着急;大学毕业了,大家纷纷带着行里准备赶火车,可我不知怎么弄的,竟然收拾出十几个大包裹,摆了一地。一个人根本拿不走,想让同学帮忙又很难,因为人家也是大包小裹的,根本没有更多的手来相助,怎么办?过一会儿,火车就要开……

    在绘画方面,梦境表达的结果就是,从此诞生了超现实主义画派。据说,胡安·米罗的画常源于记忆和他的梦境,因而其作品就被人们称为“梦幻绘画”。这位西班牙画家是和毕加索、达利齐名的20世纪超现实主义绘画大师之一。他享年90岁的高寿是不是与他美妙的空想、作品洋溢的自由天真的气息和热情的活力有关呢?

    不知过了多久,我彻底迷失于迷宫木楼之地。想爬墙过檐、登上房顶,看看到底哪里才是走出这个迷宫的正确方向。忽然,从睡梦中惊醒一位七旬太婆。她推开户,不解地问道:“小伙子,你在找水喝吗?”

    至于庄周梦蝶的故事,因为是上升到了抽像的哲学层面,我们就不能用打梦机,只打一张“庄周+蝴蝶”的简单画面,应该改用“录梦机”(梦境录像带)来仔细观察几个重要的过程与节点:庄子在梦中是怎么幻化为蝶的?化为蝴蝶后,他干了什么?在梦中,蝴蝶是不是也曾变成过庄子,它又干了什么?梦醒之后,蝴蝶又是怎样复化成庄子的?庄子重回现实,也就是梦醒之后,又作了什么思考?这几个环节,也许有助于我们理解庄子提出的伟大观点:“外部事物都会与自身交合相融,即,万事万物最后都是要合而为一的。大道时而化为庄周,时而化为蝴蝶,这就是物化”。

    捡到10元钱,难道这就是书上说的“交到了好运气”吗?《周公解梦》里的说法未免迷信,只能把它当作一个解闷取乐的活动看待。不过,我还是想弄明白,自己为什么会总做同一类的梦呢?一年里竟然被吓醒好几次。

    奶奶也被惊醒,给10岁的我倒了一杯水,安慰道:“你是因为口渴才做了恶梦的。不用害怕,梦见被黄狗追咬,将来会发财的。”

    存于你心之所期的未来里,驻于你生命之花的灿烂间,舞于你灵魂深处的秘语中,内心之所往所向,生命的不息之气,心灵的博动之声;学会听从、聆听、感受、欣赏,如此便好;你又会在那依稀的静夜里发出梦魇中曾经的呼唤与呐喊;那睡着的梦,清醒的梦,半睡半醒的梦;那甜梦、奇梦、苦梦;那成长之梦,理想之梦,怀旧之梦,践行之梦;你总会在夜的沉寂中一次一次把我们惊醒,让我们在审视、自省和不断觉悟中懂得更多,心向梦和远方,纵然前路坎坷、水复山重……

    萨尔瓦多·达利被誉为最伟大的超现实主义画家、天才与想象力非凡的艺术巨匠。无论谁看到达利的油画,总归是要问几个问题的,他为什么会画出那么不可思议的幻想世界?达利的大脑里到底装了些什么,才会如此与众不同?其实,达利受心理学家弗洛伊德的影响很大,他喜欢描绘梦和潜意识。也就是说,达利的画作完全就是他的梦境。他的双手就是“打梦机”的输出终端,他的每一个梦境就是一幅幅奇异的作品,只不过放在了他的大脑这个天然的储存机里,随用随打而己。

    这就是诗人在梦中呈现出的神奇瑰丽、虚无飘渺的奇景。它给人的感觉是,亦虚亦实、亦幻亦真,形象辉煌流丽,感慨深沉激烈,极富浪漫主义色彩。可惜,到现在我们还没有发明出“打梦机”,否则就能捕捉和录制下李白当年这个奇丽的梦境场面。我想,他的“梦境录像”一定是栩栩如生、波澜壮阔的。假如您有一双妙手,不妨试着配一幅画?

    救星总算来了,老远的地方,望见弟弟正从附近路过,他还不知道我此刻的处境。于是,我放大了嗓门,“弟弟,快拿木棒,快来,救我!”

本文由奥门金沙网址发布于技术,转载请注明出处:前后端渲染,梦境与打梦机

上一篇:生日快乐,芳华犹在 下一篇:没有了
猜你喜欢
热门排行
精彩图文