文章目录

现阶段手头上的工作主要有两块,两份工作均告一段落,但日后可能有新的需求或者异常。所以记录一下两块项目的工作内容和具体的思路,方便其他人维护。

下面列一下具体内容:

  • 翼萨项目
    • 生成一系列docx文档
  • 同洲易题项目
    • docx转json(划重点)
    • 按数据生成xlsx
    • 解析xlsx
    • 根据后台题目数据生成简单试卷,格式为docx
    • 收藏功能本地数据库库同步

翼萨项目

项目地址

http://develop.coolcto.com/lipengcheng/yisa-consulting-services-portal-frontend

工作内容

从两个数据源取出数据,按照参数不同 ->生成多个文件,并打包,然后上传到七牛云存储,然后将url返回给前端

流程图

yisa流程图.png

项目设计

因为基本上可以说是从一个数据源,然后生成多个文件的过程。 项目采用的是模板替换的方式,从模板的docx文件,标记文字,然后替换其中的标记。

目前在项目中只能标记图片和文字,不能标记表格,标记如图所示、

标记文字使用{key}

QQ图片20170525134839.png

优点

  • 开发速度快
  • 添加的文字随模板文件的字体样式和格式

缺点

  • 需要通过hack的方式去应对项目方奇葩的需求

举个栗子,项目放需要根据不同数目的(董事+监事+经理) 生成不同数目的表格。我用了hack的方式,设置了多个不同模板,然后根据js去判断数量,然后选用不同的模板。

QQ截图20170525135549.png

看着上面整齐划一的模板,我的内心是崩溃了。 产品经理,在项目开始的时候,不是说好了没有这种诡异的需求了么?

  • 需要严格控制模板的格式和变量名

举二个栗子, 针对表格内填充图片的行为,需要提前设置好表格中单元格的宽高,以免产生与预期不匹配

采用统一的数据处理(下文中的dataMiddleHandle.js文件),模板内相应的地方都需要填入对应的变量名

  • 无法替换表格

主要文件及位置

\mewchan\node_modules\docxmodule
//存放docx模板的文件
\mewchan\node_modules\docx.js
//生成模板文件的封装

\mewchan\node_modules\dataMiddleHandle.js
//数据处理中心
\mewchan\kitties\moduledocx
//接口及处理处理除数据外其他逻辑的地方

使用的插件

  • docxtemplater

  • docxtemplater-image-module

  • Downloader

    • 用途:other的下载包,用于下载将替换到模板的图片从七牛下载到本地
    • 地址:
  • Uploader

    • 用途:other在七牛官方包上的进一步封装,提供往七牛上传文件的服务。在本项目中,用于将生成的docx和压缩包上传到七牛,然后提供url给前端。
    • 地址:
  • other_client.js

    • 用途:other在http请求上的封装,用于给后端发送jsonrpc
    • 地址:

易题项目

项目地址

http://develop.coolcto.com/zhujunwei/e_teach_clean

工作内容

  • docx转json(划重点)
  • 按数据生成xlsx
  • 解析xlsx
  • 根据后台题目数据生成简单试卷,格式为docx
  • 收藏功能本地数据库库同步

docx转json

将带有标记的试题题目的文档转化成json并传到后端。 docx内的格式如下

第一段文字为该试卷的标题
1.   //这里是题号
#
这里是题目内容
#
*
这里是答案
*
{
这是是对答题卡的设置
}

流程图

docx转json.png

项目设计

本质上,docx就是一个xml文档的zip压缩包。

由于历史遗留原因,目前的总的设计是将docx —>text —>json

个人觉得,这是一个坑比较大的项目,主要集中在以下三点:

主要可能维护的地方

  • docx转text,目前是流式处理,遇到不能解析的格式或者文字,则忽略,但由于目前所查的docx资料有限,不能保证office不坑我们。目前小规模测试暂无异常。目前转换的结果存储在path.join(os.tmpdir(),'translate.txt'),可以靠看这个文件去排错。

  • text转json, 大坑。目前由于减小客户在往系统里面撸题目的时候尽量简便,所以判断的逻辑很复杂。目前是按行去读取text,然后用状态和正则去记录和判断题干,小题,小题中的小题。不排除客户会用稀奇古怪的序号去标记小题目,导致正则无法判断。目前转换为json的结果存储在path.join(os.tmpdir(),'result.json')

  • text转json后给每道题目加上类型。最开始只是前端需要根据这个类型去给每个题目套上不同的样式。这个判断并不可靠,只是应急方案。目前判断依据 是有无()或者____,有无选项或者小问。详细判断逻辑参照\mewchan\node_modules\TextToJson\addType.js.

主要文件及位置


\mewchan\brain\servlet.js
//处理上传请求接口,会把请求转给handler.js处理

\mewchan\brain\handler.js
//处理请求逻辑

\mewchan\brain\init.js
//在程序初始化时检测如果是win平台且没有拷贝过,则拷贝 转换图片的应用程序到缓存目录

\mewchan\brain\result.json
//报错信息汇总

\mewchan\brain\config.js
//配置文件

\mewchan\node_modules\docx2Text
//自己写的docx转txt模块

\mewchan\node_modules\TextToJson
//将docx转好的txt,再转为txt。因为需要对题目

\mewchan\node_modules\errorList.js
//报错处理

\mewchan\node_modules\imageConvert.js
//将docx内微软格式的图片,转换为可以在页面上显示的图片类型。依赖于imagemagick程序

\mewchan\node_modules\uploadTemp.js
//将文件上传到七牛

docx内xml文档标记的一些参考资料

https://msdn.microsoft.com/en-us/library/office/gg278308.aspx

https://msdn.microsoft.com/en-us/library/office/gg278323.aspx

https://msdn.microsoft.com/en-us/library/office/ee922775(v=office.14).aspx

这个网站是我的主要参考源 http://officeopenxml.com

http://www.docin.com/p-428010508.html http://www.taguage.com/tag/55f14c4674ebc826528da22f http://www.bubuko.com/infodetail-1290603.html http://blog.csdn.net/u010371710/article/details/51966236

使用的插件

  • multer

  • Uploader

    • 用途:other在七牛官方包上的进一步封装,提供往七牛上传文件的服务。在本项目中,用于将解析的docx中的图片和公式(根据公式生成的docx文档)上传到七牛,然后将返回的url塞进json传给后端。
    • 地址:
  • @.fs.unzip()

    • 用途: 将docx解压,以便读取其中的xml文档
    • 地址: 参照what中mewUtil文档
  • imagemagick

    • 用途:docx内有一些图片和公式的格式为微软官方支持的wmf和emf等图片,不能在前端网页直接显示,所以需要通过插件将这些图片格式转换好。
    • 文件路径: \mewchan\brain\imageconvert.zip
    • 地址: http://www.imagemagick.org/script/index.php
  • other_client.js

    • 用途:other在http请求上的封装,用于给后端发送jsonrpc
    • 地址:

按数据生成xlsx

用于 方便客户下载一个excel文档,从题库生成试卷用到的,在excel内选择需要添加的题目类型,考察的知识点啊。由于excel如果任由客户发挥的话,也挺污的。所以自己写了一个拼接xml然后打包生成excel的。提供

  • 单元格可填写文字
  • 单元格可使用下拉单选框
  • 指定区域外的单元格不能编辑

这三个定制功能. 详细可参考\mewchan\node_modules\excelCreater\README.MD

如果后续有更多的要求,建议使用 exceljs替代

解析xlsx

主要使用的是node-xlsx, 因为mew_js系统目前不支持ES7,所以对其中部分代码从ES7->ES6。然后在外面包了一层,保证取出的数据符合后端需要的格式。具体详见\mewchan\node_modules\xlsx目录

根据后台题目数据生成简单试卷,格式为docx

根据前端发过来的订单号,从后台取出数据,然后生成试卷。

项目设计

目前的需求是从后台取出数据,然后依次下载图片和公式,给题目的选项和小问加上序号(这个依赖于解析docx加上的题目类型)。然后根据数据生成docx;

理论上讲,因为数据都是从后台拿的,源数据是解析docx得到的,不会有过多的问题。

主要文件及位置

\mewchan\node_modules\createPaperAdapter
//依赖包为docxCreater,根据json生成docx文档

使用的插件

收藏功能本地数据库库同步

项目设计

用户端界面,有一个收藏题目的功能,方便用户快速的把收藏的题目放到试卷内。由于功能较为简单,且放在后台有点脏,所以放在用户端了。但随之而来的问题就是。用户可能换电脑。所以需要 数据库同步。目前采用的流程详见流程图。

需要注意的两个小细节 + 前端传给node的数据库更新不及时(服务器依赖于session),前端判定需要库同步是在刷新页面上。所以上传完成的数据库需要通知前端

  • 如果用户在短时间内频繁触发下载和上传数据库逻辑,可能会带来问题。所以分别设定了开关

### 流程图

数据库库同步逻辑.png

主要文件及位置

\mewchan\kitties\e_teach\database.sql
//创建数据库的sql语句

\mewchan\node_modules\replaceSQL.js
//替换数据库的代码

\mewchan\kitties\e_teach\index.js
//数据库增删改查 以及 同步数据库逻辑的代码(hack一些可能出现的问题)

使用的插件

  • sql.js, mdbc.js, sqlite.js

    • 用途: other的操作数据库三件套
    • 地址:
  • Uploader

    • 用途:other在七牛官方包上的进一步封装,提供往七牛上传文件的服务。在本项目中,上传数据库文件。
    • 地址:
  • Downloader

    • 用途:other的下载包,用于下载数据库
    • 地址:
  • other_client.js

    • 用途:other在http请求上的封装,用于给后端发送jsonrpc
    • 地址:

写在最后

之前提到了exceljs包。附上一段自己的测试代码。

当然,也可以直接去看它的官方文档


var Excel = require('exceljs');
var workbook = new Excel.Workbook();
var worksheet =  workbook.addWorksheet('sheet', {
  pageSetup:{paperSize: 9, orientation:'landscape'}
});

//设置行高,符合预期值
worksheet.getRow(1).height = 42.5;

// 可以设置单元格的列宽,实际列宽是9.38,31.38,9.38
worksheet.columns = [
    { header: 'Id', /*key: 'id', */width: 10 },
    { /*header: 'Name',*/ key: 'name', width: 32 },
    { /*header: 'D.O.B.',*/ key: 'DOB', width: 10, outlineLevel: 1 }
];

//合并单元格测试有效
worksheet.mergeCells('A4:B5');
worksheet.getCell('B5').value = 'Hello, World!';

//上下和垂直居中测试有效
worksheet.getCell('B5').alignment = { vertical: 'middle', horizontal: 'center' };

// 测试边框,只对单元格有效
// 边框的粗细为最细
worksheet.getCell('B6:C10').border = {
    top: {style:'thin'},
    left: {style:'thin'},
    bottom: {style:'thin'},
    right: {style:'thin'}
};

// 测试单元格背景颜色
worksheet.getCell('C10').fill = {
    type: 'pattern',
    pattern:'solid',
    // bgColor:{argb:'CCFFFF00'}
    fgColor:{argb:'FFCCFFFF'}
};
worksheet.getCell('C10').value = "测试";

worksheet.getCell('C11').fill = {
    type: 'pattern',
    pattern:'solid',
    // bgColor:{argb:'EEF7FF00'}
    fgColor:{argb:'FFEEF7FF'}
};
worksheet.getCell('C11').value = "测试";

// 测试更改字体的一些属性
worksheet.getCell('C12').font = {
    name: 'Comic Sans MS',
    // family: 4,
    // size: 16,
    // underline: true,
    bold: true,
    color: {argb:'FFEEF7FF'}
};
worksheet.getCell('C12').value = "测试2"

//数字格式按照这样处理是可以的;
worksheet.getCell('C13').value = "11.212323"


//测试直接添加二维数组
worksheet.addRows([[111,222,333],["shenme","shenme"]]);

//测试输出文件
workbook.xlsx.writeFile("./1.xlsx")
    .then(function() {
       console.log("done")
    });

总浏览数:
总访客数: