美文网首页nodejsweb前端
如何将word转为好看的导航网页?

如何将word转为好看的导航网页?

作者: 姜治宇 | 来源:发表于2021-11-29 15:29 被阅读0次
最近接到这样一个需求,产品那边用word写了一个用户手册,要求转为导航类网页,样式大概是这样的: page.png

手册比较大,word大概有一百多m的样子,从头开发网页的话太浪费时间,能否自动生成呢?
自动生成的思路是:
1、开发一个上、左、右的导航网页,头部和左侧目录导航自己定制开发,而右侧使用word直接转成的html。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>导航页</title>
</head>
<body>
    <div style="float:left;width:30%;height:500px;background:red;">
        <a onclick="toPage('b.html#A1')">1、《热爱生命》</a><br/>
        <a onclick="toPage('b.html#A2')" >2、《雪狼》</a><br/>
        <a onclick="toPage('b.html#A3')" >3、《荒野的呼唤》</a><br/>
        <a onclick="toPage('b.html#A4')" >4、《海狼》</a><br/>
    </div>
    <div  style="float:right;width:60%;height:500px;background:green;">
        <iframe src="b.html#A2" id="frm" frameborder="0" style="width:100%;height:100%;"></iframe>
    </div>
</body>
<script>
    function toPage(url){
        var page = document.getElementById('frm');
        page.setAttribute('src',url);
    }
</script>

我们将word右键另存为,保存为网页的形式。
注意,word默认保存的是gb2312的编码,而我们常用的是utf8编码,需要这样转一下。

a.png
保存完之后,会有一个htm文件和一个文件夹。打开网页,我们发现自动生成的目录是这样的: b.png
一级二级三级菜单都是扁平结构的,而我们一般开发的目录菜单,都是带层级的嵌套ul li结构。
所以难点就在于:
如何将word生成的目录,与我们开发的左侧导航联系起来?
以下是我的解决方案。主要是利用node的cheerio包,将扁平结构的目录,转成带层级的数据结构,然后再生成树结构。
目录处理完后,将word生成的目录部分去掉即可。
const fs = require('fs');
const cheerio = require('cheerio');

//=================================生成内容================================================//
async function handleContent(path,destPath) { //需清除word的目录
    let newHtml = await fsRead(path);
    let $ = cheerio.load(newHtml);
    let bodyPart = $('body').html();

    let $d = cheerio.load(bodyPart);
    $d('.MsoToc1').parent().replaceWith('');
    $d('.MsoTocHeading').replaceWith('');
    $d('.MsoTitle').replaceWith('');
    $d('body').append(`<script src="../layout/jquery.min.js"></script>
    <script>
    $('img').parents('p').removeAttr('style').css('text-align','left');
    </script>`);
    let res = await fsWrite(destPath, $d.html());//生成处理过的html
    if (res === 'ok') {
        console.log('内容处理完毕');
    } else {
        console.log('内容处理出错了');
    }
}


//=================================生成目录================================================//
async function handlecatalogue(path, destPath) {
    let content = await fsRead(path);
    let listHtml = getHtml();//读取目录文件
    let arr: any[] = [];
    let count = 0;
    let count1 = 0;
    let count2 = 0;
    let $ = cheerio.load(content);
    let $list = cheerio.load(listHtml);

    $('.MsoTocHeading').eq(0).siblings('p').each((key, element) => {

        let className = $(element).attr('class');

        if (className === 'MsoToc1') { // 一级目录
            $(element).find('a').each((k, v) => {
                count++;
                let url = $(v).attr('href');
                let title = $(v).text().replace(/\.{1,}\s+\d+/ig, '');
                let obj = { id: count, title: title, url: url, parent: 0 };
                arr.push(obj);

                count1 = count;

            });

        }
        if (className === 'MsoToc2') { // 一级目录
            $(element).find('a').each((k, v) => {
                count++;
                let url = $(v).attr('href');
                let title = $(v).text().trim().replace(/\.{1,}\s+\d+/ig, '');
                let obj = { id: count, title: title, url: url, parent: count1 };
                arr.push(obj);
                count2 = count;

            });


        }
        if (className === 'MsoToc3') { // 一级目录
            $(element).find('a').each((k, v) => {
                count++;
                let url = $(v).attr('href');
                let title = $(v).text().trim().replace(/\.{1,}\s+\d+/ig, '');
                let obj = { id: count, title: title, url: url, parent: count2 };
                arr.push(obj);

            });
        }
    });

    let newarr = convertData(arr);
    let nodes = createTree(newarr, true);
    $list('.left-part').html(nodes);
    let res = await fsWrite(destPath, $list.html());//生成处理过的html
    if (res === 'ok') {
        console.log('目录处理完毕');
    } else {
        console.log('目录处理出错了');
    }
}





//==================================生成html=======================================================//
function createTree(list, flag = false) {

    if (Array.isArray(list)) {

        let str = '';
        if (flag) {
            str = `<ul class="lp-cont">`;//最外层ul
        } else {
            str = `<ul class="lp-cont-child">`;
        }
        list.forEach(item => {
            str += `<li onclick="toPage('./pages/book.html${item.url}')">${item.title}`;
            if (item.children && item.children.length > 0) {
                str += createTree(item.children);
            }
            str += `</li>`;
        });
        str += `</ul>`;
        return str;
    }



}
//======================================生成tree data============================================//
function convertData(jsonData) {
    var result: any[] = [], temp = {}, i = 0, j = 0, len = jsonData.length;
    for (; i < len; i++) {
        temp[jsonData[i]['id']] = jsonData[i] // 以id作为索引存储元素,可以无需遍历直接定位元素
    }
    for (; j < len; j++) {
        var currentElement = jsonData[j]
        var tempCurrentElementParent = temp[currentElement['parent']] // 临时变量里面的当前元素的父元素 parentId 父级ID
        if (tempCurrentElementParent) { // 如果存在父元素
            if (!tempCurrentElementParent['children']) { // 如果父元素没有chindren键
                tempCurrentElementParent['children'] = [] // 设上父元素的children键
            }
            tempCurrentElementParent['children'].push(currentElement) // 给父元素加上当前元素作为子元素
        } else { // 不存在父元素,意味着当前元素是一级元素
            result.push(currentElement);
        }
    }

    return result;
}

//======================================读文件====================================================//
function fsRead(filename) {
    return new Promise((resolve, reject) => {
        fs.readFile(filename, { flag: 'r', encoding: 'utf-8' }, function (err, data) {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        })
    })
}

//===================================写文件===================================================//
function fsWrite(path, content) {
    return new Promise((resolve, reject) => {
        fs.writeFile(path, content, { flag: 'w', encoding: 'utf-8' }, (err) => {
            if (err) {
                reject(err);
            } else {
                resolve('ok');
            }
        })
    })
}
//====================================目录文件=====================================================//
function getHtml() {
    return `
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户手册</title>
    <style>
    body{
        margin:0;
        padding:0;
    }
    ul{
        margin:0;
        padding:0;
        list-style:none;
        /* margin-bottom:15px; */
    }
    ul li{
        position: relative;
        line-height:40px;
    }
    
    .container{
        width:100%;
        height:100%;
        display:flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .header{
        width:inherit;
        height:50px;
        display:flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        color:#fff;
        background:#000;
    }
    .h-back{
        
        width:20px;
        height:20px;
        margin-left:15px;
        margin-right:20px;
    
    }
    .content{
        width:inherit;
        height:calc(100vh - 50px);
        display:flex;
        flex-direction: row;
    
        justify-content: center;
    
    }
    .left-part{
        width:30%;
    
        display:flex;
        flex-direction: column;
        overflow-x:hidden;
        overflow-y: auto;
        
    }
    .lp-title{
        font-weight: 400;
        color: #666666;
        margin-left:180px;
        margin-top:30px;
    }
    .lp-cont{
        margin-left:180px;
        margin-top:15px;
    }
    .lp-cont li{
        font-size:16px;
        font-weight: 400;
    
        /* color: #097EFF; */
        color:#333333;
       
    }
    .lp-cont li:hover{
        cursor: pointer;
    }
    .right-part{
        width:70%;
        margin-left:16px;
    }
    .clear-bar{
        width: 183px;
        height: 1px;
        background: #000000;
        opacity: 0.1;
        margin-top:10px;
    }
    .lp-cont-child{
        display:none;
        position: relative;
    
        left:16px;
    }
    .lp-cont-child li{
        font-size:14px;
    }
    
    .lp-cont-cate::before{
        content:"";
        
        position: absolute;
        top:17px;
        left: -15px;
        border-top:6px solid #999999;
        border-left:5px solid transparent;
        border-right:5px solid transparent;
        -webkit-transform: rotate(-90deg);
        -moz-transform: rotate(-90deg);
         -ms-transform: rotate(-90deg);
          -o-transform: rotate(-90deg);
             transform: rotate(-90deg); 
        
    }
    .li-active::before{
    
        -webkit-transform: rotate(0deg);
           -moz-transform: rotate(0deg);
            -ms-transform: rotate(0deg);
             -o-transform: rotate(0deg);
                transform: rotate(0deg); 
    }
    .active{
    
        color: #097EFF !important;
    }
    </style>
    <script src="./layout/jquery.min.js"></script>
</head>

<body>
    <div class="container">
        <div class="header">
            <img class="h-back" src="./layout/arrow-left.png" onclick="goBack()" />
            <div class="h-title">用户手册</div>
        </div>
        <div class="content">

            <div class="left-part">

            </div>
            <div class="right-part">
                <iframe id="frm" src="./pages/book.html" frameborder="0" style="width:100%;height:100%;"></iframe>
            </div>
        </div>
    </div>

</body>

</html>
<script>

    let lp = document.querySelector('.lp-cont');
    $('.lp-cont-child').parent().addClass('lp-cont-cate');//增加类
   
    lp.addEventListener('click', function (e) {

        if (e.target.tagName.toLowerCase() === "li") {
            e.stopPropagation();
            let element = $(e.target);//目标节点
            if (element.children('.lp-cont-child').length > 0) {
                element.removeAttr('onclick');
                if (element.hasClass('li-active')) {
                    element.removeClass('li-active');
                    element.children('.lp-cont-child').slideUp();
                } else {
                    element.addClass('li-active');
                    element.children('.lp-cont-child').slideDown();
                }
            } else {

                $('li').removeClass('active');
                element.addClass('active');
            }
        }
    });

    function toPage(url) {
        var page = document.getElementById('frm');
        page.setAttribute('src', url);
    }

    function goBack() {
        location.href = '/';
    }
</script>
`;
}
export { handlecatalogue, handleContent, fsWrite };

相关文章

  • 如何将word转为好看的导航网页?

    最近接到这样一个需求,产品那边用word写了一个用户手册,要求转为导航类网页,样式大概是这样的: 手册比较大,wo...

  • 微信文章存为word

    1.网页内容(文字部分)点击 右键,然后 打印 保存了,是pdf格式 3.如果需要word,pdf转为word吧

  • 基于办公文书转HTML工具

    标签 其他word转换方法的比较 转换方法:将Word另保存,格式改为网页,再使用浏览器打来其网页,最后在网页查找...

  • 通过UIWebView加载本地网页

    方法一: 先得到本地网页的全路径,再通过全路径将网页内容转为 NSData数据,最后将NSData转为NSStri...

  • 网页导航

    新闻人民网 | 澎湃新闻 | 端新闻? | 人民日报海外版 | 纽约时报 | ...

  • pdf怎么转成jpg最简单

    pdf转为jpg,以及pdf转为word、pdf转为ppt格式等操作,在日常的文档交流中难免会使用到。第一种土豪的...

  • 如何将word/文本一键转为漂亮的PPT

    如果大家用的是微软家的OFFICE套装,那么可以利用word和ppt之间的互动,实现文本到ppt的转换。但是这种方...

  • 如何统计各科期末成绩汇总

    一、如何将word文本变成表格? 首先在word文档中选插入表格,选文本转换成表格,在制作之前,要将word文本每...

  • HTML 转 Word API 接口

    HTML 转 Word API 接口 支持网页转 Word,高效转换为 Word,提供永久链接。 1. 产品功能 ...

  • 重新认识组件-面包屑导航

    什么是面包屑导航 面包屑导航是网页设计中极为常见的一种设计方法,我们经常使用面包屑导航来作为网页导航框架中的辅助手...

网友评论

    本文标题:如何将word转为好看的导航网页?

    本文链接:https://www.haomeiwen.com/subject/htqotrtx.html