阅读 560

从Google Sheets内容的导出,到字符串换行问题

1,Google Sheets内容的导出

1,Google Sheets API 指南

因为想直接在浏览器web环境下实现,按照官方指南,操作如下:

1.1,准备内容

1.1.1,一个 Google 账号

1.1.2,一个可以提供 web 服务的配置

如果有Python环境,

python 2.x python -m SimpleHTTPServer 8000

python 3.x python -m http.server 8000

如果有PHP环境,

php -S 0.0.0.0:8080

或者,可以通过webstorm打开html文件时,也可以启动 http://localhost:63342

需要注意的是,无论通过何种方式,注意端口号,之后需要再其他地方使用。

1.2,步骤

1.2.1,Google 控制台 注册应用

1

2
3,注意这里直接点 取消
4,创建凭据

一定要先创建client ID

跳转的页面,点击最右侧 配置同意屏幕

再跳转的页面,只需要填写 应用名称电子邮件地址,再点击最下方 保存 即可。

这里选择 网页应用

再定义 名称 和配置 限制JavaScript的来源

注意端口号要和 1.1.2 中保持一致!

5,再创建API密钥,创建后关闭弹窗即可。

6,此时,就有了 API密钥client ID

1.3,套用模板,使用API

新建一个index.html,复制如下代码

demo

更改这2个变量为刚刚创建的 API密钥 和 client ID

更改第1个参数为,自己的Google账号创建的Excel文档对应的网址后缀。

更改第2个参数为,excel工作簿的名称和工作表的范围限制。

如下表示的是从A2单元格所在列开始,到第E列结束的所有内容。

// 这个函数用于发送请求,拿到文档的内容,
// 所以目标就是格式化响应的结果。
function listMajors() {
    gapi.client.sheets.spreadsheets.values.get({
      spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms',
      range: 'Class Data!A2:E',
      
    }).then(function(response) {
      var range = response.result;
      if (range.values.length > 0) {
        let titleName = ''
        let obj = {}
        let result = range.values.map((row) => {
          row = row.map((r, i) => {
            if (r.indexOf('\n') != -1) {
              r = r.split('\n').map(item => `<p>${item}</p>`).join('\n')
            }
            return r
          })

          let lastContent = row[row.length - 1]
          let nameIndex = lastContent.indexOf('title')

          if (nameIndex != -1) {
            titleName = lastContent.split('|')[1]
          } else {
            obj[`${titleName}.${lastContent}`] = row[0]
          }
        });
        let objStr = JSON.stringify(obj, null, 4);
        // pre是textarea标签
        var pre = document.getElementById('content');
        pre.innerHTML = objStr.replace(/\\n/g,'&#10;')
        console.log(obj)
      } else {
        appendPre('No data found.');
      }
    }, function(response) {
      appendPre('Error: ' + response.result.error.message);
    });
  }
复制代码

1.4,启动和打开

使用web服务器启动 localhost:8000(或自定义的其他端口),并打开这个index.htm。

在页面中点击授权,即可看到格式化的结果。

2,字符串换行问题

2.1,普通的JSON格式化

将如下的结果放到<pre>标签中,就可以实现在页面中显示JSON字符串格式化后的结果。

let obj = {
    'language': '中文',
    'nav': '左侧:首页',
    'congrat': '🚀恭喜 🚀 ',
  }
// 第3个参数,指定缩进的空白字符串
let objStr = JSON.stringify(obj, null, 4);
// 所有换行符替换为br标签。
let html = objStr.replace(/\n/g, '<br>');
复制代码

2.2,第一个问题

如果属性值中有 html标签 ,怎样将标签显示在页面中,而不转义?

let obj = {
    'language': '中文',
    'nav': '左侧:首页',
    'congrat': '🚀恭喜 🚀 ',
    'tips': '<p>前端的乐趣</p>' +
    '<p>1. 代码千万行,注释第一行</p>' +
    '<p>2. 编码不规范,测试两行泪</p>'
  }
  
let objStr = JSON.stringify(obj, null, 4);
// 所有换行符替换为br标签。
let html = objStr.replace(/\n/g, '<br>');
复制代码

如上操作,结果如下:

<p>标签生效了

解决:将标签替换为大于小于号(这只是一种方案,还有其他方案)。

  let html = objStr.replace(/\n/g, '<br>').replace(/<p>/g, '&ltp&gt').replace(/<\/p>/g, '&lt/p&gt');
复制代码

2.3,第2个问题

问题1:如果还有其他标签,每个都得进行转换,而且不能将<br>标签进行转换了,使用正则替换< >也有点麻烦。

问题2:对象的属性值,不像之前那样,在指定位置换行了。(p标签失效带来的问题)

在尝试过很多次之后发现一个情况,

如果仅仅只是一个字符串变量,想让它在指定位置换行,很随意,只需要在指定位置插入换行符\n即可。

但作为对象的属性值,也就是说,保持JSON字符串格式化之后的这种显示方式,通过\n是无法让对象的属性值在指定位置换行的。

解决

将结果放到文本域<textarea>中,

注意是放到文本域的 innerHTML 中,不是 value属性!

let obj = {
    'language': '中文',
    'nav': '左侧:首页',
    'congrat': '🚀恭喜 🚀 ',
    'tips': '<p>前端的乐趣</p>' + '\n' +
    '<p>1. 代码千万行,注释第一行</p>' + '\n' +
    '<p>2. 编码不规范,测试两行泪</p>'
  }
  
let objStr = JSON.stringify(obj, null, 4);
// 注意是 \\n,因为这里要匹配的是 '\n',而不是对象中隐式的换行符
// 如果使用的是es6的``,手动换行,自带\n,和对象中的还是不一样。
// 所以,一定要使用\\n
// &#10; 是在textarea中,特有的可以进行换行的符号。
let html = objStr.replace(/\\n/g,'&#10;')
复制代码

另外,例子中obj对象的 tips 属性,可以使用 es6 推出的 `` 拼接字符串,更方便一点:

注意:如果使用 `` ,就要进行手动换行,最终结果才能换行!

let obj = {
    'language': '中文',
    'nav': '左侧:首页',
    'congrat': '🚀恭喜 🚀 ',
    'tips': `<p>前端的乐趣</p>
    <p>1. 代码千万行,注释第一行</p>
    <p>2. 编码不规范,测试两行泪</p>`
  }
复制代码

最终效果,可以直接全选复制到其他地方。

为什么要如此费神折腾这个?

因为,将其按自己定义的格式化后,可以直接复制到代码中,不需要再手动一个个的进行换行。

这样清晰直观,利于维护。

欢迎指正和提出其他的实现方式。O(∩_∩)O~~

结束

文章分类
前端
文章标签