首页 前端知识 【react】动态页面转换成html文件下载,解决样式问题

【react】动态页面转换成html文件下载,解决样式问题

2024-06-10 11:06:47 前端知识 前端哥 644 827 我要收藏

需求

今天遇到一个需求,挺恶心人的,将一个在线文档页面,可以导出成为html页面查看。

看到网上有使用fs模块,通过react的ReactDOMServer.renderToStaticMarkup将组件转成html字符串,输出文件了。
但是我尝试了,发现引入的fs为空,我就愁思,这个node环境下的模块,在react项目中能用么,一想到这里,自己真的是太笨了,肯定的不适用啊。fs是node模块,除非是next.js,不然用不了。

解决

思路类似,获取页面上渲染完成的dom字符串,通过a标签下载

URL.createObjectURL(file)

const fileName = `${name}.html`;
  const file = new File([htmlWithStyles], fileName, { type: 'text/html' });
  const oUrl = URL.createObjectURL(file);
  const a = document.createElement('a');
  a.style.setProperty('display', 'none');
  a.href = oUrl;
  a.download = file.name;
  document.body.appendChild(a);
  a.click();
  a.remove();
  const delay = 10000;
  setTimeout(() => URL.revokeObjectURL(oUrl), delay);

但是问题来了,发现下载的文件样式不存在 需要引入外部样式或者在写在style标签中

  const htmlWithStyles = `
  <html>
    <head>
    <style>${styles}</style>
    </head>
    <body>
      <div style="display:flex; height: 100%;">
      ${html}
      </div>
    </body>
  </html>
`;

笨人方法只有这样了,再高级点的,俺也不会

代码

这里的styles是外部定义的
要跟下载后的html里面的classname要对应,毕竟react项目跑起来的样式是加了很多前缀,比如这样
在这里插入图片描述
还有一个问题,就是使用的antd的表格,样式实在是太多了,但是还是要copy进去,不然静态页面样式就缺失了,从原本的页面里面,index.less进去,把所有的跟table相关的样式都copy过来。
在这里插入图片描述
在这里插入图片描述
所以说这个需求感觉没啥难度,但是又挺麻烦的。

封装方法

export function downHtmlFile({ html, name }) {
  // 创建包含外部样式链接的 HTML 字符串
  const htmlWithStyles = `
  <html>
    <head>
    <style>${styles}</style>
    </head>
    <body>
      <div style="display:flex; height: 100%;">
      ${html}
      </div>
    </body>
  </html>
`;
  const fileName = `${name}.html`;
  const file = new File([htmlWithStyles], fileName, { type: 'text/html' });
  const oUrl = URL.createObjectURL(file);
  const a = document.createElement('a');
  a.style.setProperty('display', 'none');
  a.href = oUrl;
  a.download = file.name;
  document.body.appendChild(a);
  a.click();
  a.remove();
  const delay = 10000;
  setTimeout(() => URL.revokeObjectURL(oUrl), delay);
}

在页面代码中使用

我是class组件,函数组件用useRef就好了,思路就是通过ref获取html字符串

 <div className={styles.con} ref={this.contentRef}>123</div>

	this.contentRef = createRef(); // 在构造方法中定义

  // 导出html文件
  handleExport = name => {
    const div = this.contentRef.current;
    if (!div) return;
    const html = div.innerHTML;
    downHtmlFile({ html, name });
  };

最后效果

在这里插入图片描述

转载请注明出处或者链接地址:https://www.qianduange.cn//article/11777.html
标签
评论
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!