提取iconfont.js 内的svg并下载
有时候同事离职、或者iconfont账号丢失之后没办法在原有的iconfont项目上添加删除图标,只能使用再添加新的图标项目
现在写了一个提取iconfont.js 内的svg并下载的html,下载成svg之后上传回iconfont,再获取在线链接替换
iconfont.js格式如下https://at.alicdn.com/t/c/font_4824150_3uaoe15bhq.js
1 window._iconfont_svg_string_4824150='<svg><symbol id="icon-shangpin" viewBox="0 0 1024 1024"><path d="M749.220285 959.524546 274.789948 959.524546c-51.92051 0-99.466386-40.037878-108.315938-91.192955l-68.476581-414.905638c-4.470825-26.03905 2.27174-52.176336 18.532075-71.474868 16.235776-19.296485 40.838104-30.356378 67.419506-30.356378L840.097038 351.594707c26.643823 0 51.251268 11.087523 67.481927 30.385031 16.229636 19.301602 22.939455 45.438888 18.370393 71.703065l-68.409043 414.423661C848.623225 919.486668 801.081443 959.524546 749.220285 959.524546L749.220285 959.524546zM183.947987 415.533948c-7.825222 0-14.44192 2.681062-18.561751 7.607258-4.1536 4.919033-5.689582 11.916401-4.378727 19.681248l68.506257 414.901545c3.452635 20.067035 24.636097 37.897122 45.275159 37.897122l474.430336 0c20.643156 0 41.827641-17.863856 45.342698-38.151925l68.410066-414.427754c1.375324-7.984858-0.160659-14.951527-4.28049-19.871583-4.154623-4.920056-10.770298-7.635911-18.59552-7.635911L183.947987 415.533948 183.947987 415.533948zM318.406329 607.378278c-35.274388 0-63.937195-28.66383-63.937195-63.910589 0-35.239596 28.662807-63.902402 63.937195-63.902402 35.210943 0 63.874773 28.66383 63.874773 63.902402C382.281101 578.680678 353.617271 607.378278 318.406329 607.378278L318.406329 607.378278zM318.406329 543.467689c0 0-0.063445 0-0.097214 0.033769l0.063445 31.921014L318.406329 543.467689 318.406329 543.467689zM703.688275 607.378278c-35.240619 0-63.904449-28.66383-63.904449-63.910589 0-35.239596 28.664853-63.902402 63.904449-63.902402 35.244712 0 63.907519 28.66383 63.907519 63.902402C767.595794 578.680678 738.932987 607.378278 703.688275 607.378278L703.688275 607.378278zM703.722044 543.467689l-0.064468 0 0.029676 31.955806L703.722044 543.467689 703.722044 543.467689zM735.671711 320.474942c-17.669428 0-31.949666-14.314007-31.949666-31.954783 0-91.444689-102.091166-159.762657-193.408965-159.762657-93.396133 0-190.019775 59.624982-190.019775 159.38301 0 17.633612-14.31503 31.949666-31.954783 31.949666-17.639752 0-31.954783-14.31503-31.954783-31.949666 0-139.763161 129.124869-223.286436 253.957992-223.286436 121.708969 0 257.317507 91.865267 257.317507 223.666082C767.626493 306.160935 753.345232 320.474942 735.671711 320.474942L735.671711 320.474942zM735.671711 320.474942" fill="#272636" ></path></symbol><symbol id="icon-shangpin1" viewBox="0 0 1024 1024"><path d="M969.728 877.568L915.968 361.984c-7.68-44.544-46.592-76.8-91.648-76.8h-136.192V221.184c0-98.304-79.872-178.688-178.688-178.688-97.792 0-178.176 80.384-178.176 178.688v64H195.584c-45.568 0-83.968 32.256-92.16 79.36L50.176 875.008c-4.608 27.136 2.56 54.784 20.48 76.288 17.92 20.992 43.52 33.28 71.168 33.28h735.744c27.648 0 53.76-12.288 71.168-33.28 17.92-21.504 25.6-49.152 20.992-73.728zM399.872 221.184c0-60.928 49.664-110.08 110.08-110.08 60.928 0 110.08 49.664 110.08 110.08v64h-220.16V221.184z m497.152 686.08c-2.56 3.584-9.216 8.704-18.944 8.704H141.824c-10.24 0-16.384-5.632-18.944-8.704-2.56-3.584-7.168-10.24-5.12-22.528L171.008 373.76c2.048-11.776 12.288-20.48 24.576-20.48H824.32c12.288 0 22.528 8.704 24.064 18.432l53.76 515.584c2.048 9.728-2.56 16.384-5.12 19.968zM413.696 476.672c0 26.624-21.504 48.128-48.128 48.128S317.44 503.296 317.44 476.672s21.504-48.128 48.128-48.128 48.128 21.504 48.128 48.128z m288.768 0c0 26.624-21.504 48.128-48.128 48.128s-48.128-21.504-48.128-48.128 21.504-48.128 48.128-48.128 48.128 21.504 48.128 48.128z" ></path></symbol><symbol id="icon-shangpin2" viewBox="0 0 1024 1024"><path d="M925.6 845.9l-80.3-499.5c-5.3-32.9-33.3-56.7-66.6-56.7h-76.2c-4.9-46.5-23.2-89.8-52.6-123.8-36.2-41.8-84.9-64.8-137-64.8-52.1 0-100.7 23-137 64.8-29.5 34-47.7 77.2-52.6 123.8h-76.2c-33.3 0-61.3 23.9-66.6 56.7l-80.3 499.5c-3.1 19.5 2.4 39.4 15.3 54.4 12.8 15.1 31.5 23.7 51.3 23.7H859c19.8 0 38.5-8.6 51.3-23.7 12.9-15 18.4-34.9 15.3-54.4zM512.9 181.1c53.9 0 99 46.8 108.9 108.6H404c9.9-61.8 55-108.6 108.9-108.6zM181.6 844l76.2-474.3H768L844.3 844H181.6z" ></path><path d="M632.4 656.3c-30.9 18.7-74.4 29.4-119.5 29.4-45.1 0-88.6-10.7-119.5-29.4-24.7-14.9-39-33.5-39-50.8l-80 0.4c0.1 24.2 8.1 48.2 23 69.5 13.2 18.9 31.6 35.5 54.6 49.4 43.6 26.4 100.8 40.9 160.9 40.9 60.1 0 117.2-14.5 160.9-40.9 23-13.9 41.4-30.5 54.6-49.4 14.9-21.3 22.9-45.3 23-69.5l-80-0.4c0 17.3-14.3 35.8-39 50.8z" ></path></symbol><symbol id="icon-31wode" viewBox="0 0 1024 1024"><path d="M899.640668 897.714805c-7.238868-108.132766-60.680011-208.738092-146.610102-276.03173l-5.16565-3.568269-0.047072 0.069585c-4.88731-2.988054-10.458189-4.586458-16.192797-4.586458-19.701714 0-31.458479 9.498328-31.458479 25.411763 0 9.266038 4.285606 17.975397 11.477402 23.882943l-0.080841 0.13917 4.562922 3.266393c72.065316 51.518351 112.638383 129.652895 120.584356 232.273111l0.084934 1.119497c-0.071631 0.862647-0.116657 1.731434-0.116657 2.612501 0 17.340947 14.058181 31.400151 31.400151 31.400151 16.759709 0 30.449499-13.131065 31.350009-29.665647l0.624217 0L899.640668 897.714805zM798.515502 371.795794c0-156.107407-128.529305-283.119149-286.524712-283.119149s-286.525736 127.011742-286.525736 283.119149c0 84.110653 37.19104 162.570609 102.377692 216.660528-117.01711 62.452377-194.688097 181.588755-203.479321 313.118394l-0.36225 5.482875c-0.007163 0.113587-0.016373 0.226151-0.022513 0.340761l-0.032746 0.499373 0.019443 0c-0.008186 0.267083-0.019443 0.533143-0.019443 0.802272 0 14.702863 11.918447 26.622334 26.622334 26.622334 14.702863 0 26.622334-11.918447 26.622334-26.622334 0-0.26913-0.01228-0.535189-0.019443-0.802272l0.553609 0 0.417509-5.467525c9.647731-124.997875 88.871073-234.450706 202.112184-279.552927 33.809013 15.705704 85.420485 32.060183 131.714857 32.060183 42.889833 0 84.540442-9.451256 124.198673-28.307719l29.048593-16.863063 23.720238-15.566534C758.567675 539.996634 798.515502 458.919061 798.515502 371.795794zM511.989767 597.931115c-126.247332 0-228.949412-101.461833-228.949412-226.157833 0-124.673487 102.701057-226.111784 228.949412-226.111784 126.259612 0 228.972948 101.438297 228.972948 226.111784C740.961692 496.469282 638.249379 597.931115 511.989767 597.931115z" ></path></symbol><symbol id="icon-dingdan" viewBox="0 0 1024 1024"><path d="M800.037628 928.016126 223.962372 928.016126c-52.980346 0-95.983874-43.003528-95.983874-95.983874l0-639.892491c0-52.980346 43.003528-95.983874 95.983874-95.983874l575.903242 0c52.980346 0 95.983874 43.003528 95.983874 95.983874l0 639.892491C896.021502 884.840585 852.84596 928.016126 800.037628 928.016126zM223.962372 159.973123c-17.545439 0-31.994625 14.449185-31.994625 31.994625l0 639.892491c0 17.717453 14.449185 31.994625 31.994625 31.994625l575.903242 0c17.717453 0 31.994625-14.277171 31.994625-31.994625l0-639.892491c0-17.545439-14.277171-31.994625-31.994625-31.994625L223.962372 159.973123z" fill="#575B66" ></path><path d="M640.924576 544.768688 287.779607 544.768688c-17.717453 0-31.994625-14.277171-31.994625-31.994625 0-17.717453 14.277171-31.994625 31.994625-31.994625l353.144969 0c17.717453 0 31.994625 14.277171 31.994625 31.994625C672.9192 530.491517 658.642029 544.768688 640.924576 544.768688z" fill="#575B66" ></path><path d="M734.84428 735.532337l-447.236687 0c-17.717453 0-31.994625-14.277171-31.994625-31.994625s14.277171-31.994625 31.994625-31.994625l447.236687 0c17.717453 0 31.994625 14.277171 31.994625 31.994625S752.561734 735.532337 734.84428 735.532337z" fill="#575B66" ></path><path d="M255.784982 305.325046c0 26.490173 21.501764 47.991937 47.991937 47.991937s47.991937-21.501764 47.991937-47.991937-21.501764-47.991937-47.991937-47.991937S255.784982 278.834873 255.784982 305.325046z" fill="#575B66" ></path><path d="M463.061986 305.325046c0 26.490173 21.501764 47.991937 47.991937 47.991937s47.991937-21.501764 47.991937-47.991937-21.501764-47.991937-47.991937-47.991937S463.061986 278.834873 463.061986 305.325046z" fill="#575B66" ></path><path d="M671.199059 305.325046c0 26.490173 21.501764 47.991937 47.991937 47.991937s47.991937-21.501764 47.991937-47.991937-21.501764-47.991937-47.991937-47.991937S671.199059 278.834873 671.199059 305.325046z" fill="#575B66" ></path></symbol><symbol id="icon-xiaoxi" viewBox="0 0 1024 1024"><path d="M821.333333 800H547.584l-86.464 96.074667a32 32 0 1 1-47.573333-42.816l96-106.666667A32 32 0 0 1 533.333333 736h288a53.333333 53.333333 0 0 0 53.333334-53.333333V234.666667a53.333333 53.333333 0 0 0-53.333334-53.333334H202.666667a53.333333 53.333333 0 0 0-53.333334 53.333334v448a53.333333 53.333333 0 0 0 53.333334 53.333333h138.666666a32 32 0 0 1 0 64H202.666667c-64.8 0-117.333333-52.533333-117.333334-117.333333V234.666667c0-64.8 52.533333-117.333333 117.333334-117.333334h618.666666c64.8 0 117.333333 52.533333 117.333334 117.333334v448c0 64.8-52.533333 117.333333-117.333334 117.333333zM704 341.333333a32 32 0 0 1 0 64H320a32 32 0 0 1 0-64h384zM512 512a32 32 0 0 1 0 64H320a32 32 0 0 1 0-64h192z" fill="#000000" ></path></symbol></svg>',(e=>{var t=(c=(c=document.getElementsByTagName("script"))[c.length-1]).getAttribute("data-injectcss"),c=c.getAttribute("data-disable-injectsvg");if(!c){var l,n,i,o,a,d=function(t,c){c.parentNode.insertBefore(t,c)};if(t&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(t){console&&console.log(t)}}l=function(){var t,c=document.createElement("div");c.innerHTML=e._iconfont_svg_string_4824150,(c=c.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",c=c,(t=document.body).firstChild?d(c,t.firstChild):t.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),l()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(i=l,o=e.document,a=!1,h(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,s())})}function s(){a||(a=!0,i())}function h(){try{o.documentElement.doScroll("left")}catch(t){return void setTimeout(h,50)}s()}})(window);
1、新建一个iconfont.js复制到里面
2、新建一个extract-icons.html,替换里面的
window._iconfont_svg_string_4824150为iconfont.js里的
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>提取SVG图标</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.status-bar {
margin-top: 20px;
padding: 10px;
background-color: #f5f5f5;
border-radius: 4px;
display: none;
}
.progress-container {
width: 100%;
background-color: #e0e0e0;
border-radius: 4px;
margin-top: 10px;
}
.progress-bar {
height: 20px;
background-color: #1890ff;
border-radius: 4px;
width: 0%;
transition: width 0.3s;
text-align: center;
color: white;
font-size: 12px;
line-height: 20px;
}
.failed-icons {
margin-top: 15px;
display: none;
}
.retry-btn {
margin-top: 10px;
background: #ff4d4f;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
.retry-btn:hover {
background: #ff7875;
}
.icon-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 15px;
margin-top: 20px;
}
.icon-item {
border: 1px solid #eee;
border-radius: 5px;
padding: 10px;
text-align: center;
transition: all 0.3s;
}
.icon-item:hover {
box-shadow: 0 0 10px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
.icon-svg {
width: 40px;
height: 40px;
margin: 0 auto 10px;
}
.icon-name {
font-size: 12px;
word-break: break-all;
color: #666;
}
.download-btn {
margin-top: 8px;
background: #1890ff;
color: white;
border: none;
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
}
.download-btn:hover {
background: #40a9ff;
}
.download-all {
margin-top: 20px;
background: #52c41a;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.download-all:hover {
background: #73d13d;
}
.header {
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="header">
<h1>iconfont SVG图标提取工具</h1>
<p>从iconfont.js中提取SVG图标并下载</p>
<div>
<button id="downloadAll" class="download-all">下载所有图标</button>
<button id="downloadZip" class="download-all" style="margin-left: 10px; background: #1890ff;">打包下载(ZIP)</button>
</div>
</div>
<div id="statusBar" class="status-bar">
<div id="statusText">正在下载图标...</div>
<div class="progress-container">
<div id="progressBar" class="progress-bar">0%</div>
</div>
<div id="failedIcons" class="failed-icons">
<h3>下载失败的图标:</h3>
<ul id="failedList"></ul>
<button id="retryBtn" class="retry-btn">重试下载失败图标</button>
</div>
</div>
<div id="iconGrid" class="icon-grid"></div>
<script src="./iconfont.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 获取SVG字符串
const svgString = window._iconfont_svg_string_4035907 || '';
if (!svgString) {
alert('未找到SVG字符串,请确认iconfont.js文件已正确加载');
return;
}
// 创建临时DOM元素来解析SVG
const parser = new DOMParser();
const svgDoc = parser.parseFromString(`<svg>${svgString}</svg>`, 'image/svg+xml');
const symbols = svgDoc.querySelectorAll('symbol');
const iconGrid = document.getElementById('iconGrid');
const iconData = [];
// 遍历所有symbol元素
symbols.forEach(symbol => {
const id = symbol.getAttribute('id');
const viewBox = symbol.getAttribute('viewBox');
const paths = symbol.innerHTML;
// 创建完整的SVG
const fullSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}">${paths}</svg>`;
// 保存图标数据
iconData.push({
id,
svg: fullSvg
});
// 创建图标项
const iconItem = document.createElement('div');
iconItem.className = 'icon-item';
// 显示SVG
iconItem.innerHTML = `
<div class="icon-svg">${fullSvg}</div>
<div class="icon-name">${id}</div>
<button class="download-btn" data-id="${id}">下载</button>
`;
iconGrid.appendChild(iconItem);
});
// 单个图标下载
document.querySelectorAll('.download-btn').forEach(btn => {
btn.addEventListener('click', function() {
const id = this.getAttribute('data-id');
const iconItem = iconData.find(item => item.id === id);
if (iconItem) {
downloadSvg(iconItem.svg, id);
}
});
});
// 下载所有图标
document.getElementById('downloadAll').addEventListener('click', function() {
if (iconData.length === 0) {
alert('没有找到图标');
return;
}
const statusBar = document.getElementById('statusBar');
const progressBar = document.getElementById('progressBar');
const statusText = document.getElementById('statusText');
const failedIcons = document.getElementById('failedIcons');
const failedList = document.getElementById('failedList');
// 清空之前的失败记录
failedList.innerHTML = '';
failedIcons.style.display = 'none';
// 显示状态栏
statusBar.style.display = 'block';
statusText.textContent = '正在下载图标...';
let completed = 0;
let failed = [];
const total = iconData.length;
// 使用更长的间隔时间避免浏览器阻止多次下载
iconData.forEach((item, index) => {
setTimeout(() => {
try {
downloadSvg(item.svg, item.id);
completed++;
} catch (error) {
failed.push(item);
completed++;
console.error(`下载图标 ${item.id} 失败:`, error);
}
// 更新进度
const progress = Math.floor((completed / total) * 100);
progressBar.style.width = `${progress}%`;
progressBar.textContent = `${progress}%`;
// 检查是否全部完成
if (completed === total) {
statusText.textContent = `下载完成,共 ${total} 个图标,${failed.length} 个失败`;
// 如果有失败的图标,显示失败列表
if (failed.length > 0) {
failedIcons.style.display = 'block';
failed.forEach(item => {
const li = document.createElement('li');
li.textContent = item.id;
failedList.appendChild(li);
});
}
}
}, index * 300); // 增加间隔时间到300毫秒
});
});
// 重试下载失败的图标
document.getElementById('retryBtn').addEventListener('click', function() {
const failedList = document.getElementById('failedList');
const items = failedList.querySelectorAll('li');
const failed = [];
// 获取失败的图标ID
items.forEach(item => {
const id = item.textContent;
const iconItem = iconData.find(icon => icon.id === id);
if (iconItem) {
failed.push(iconItem);
}
});
// 清空失败列表
failedList.innerHTML = '';
// 重试下载
failed.forEach((item, index) => {
setTimeout(() => {
try {
downloadSvg(item.svg, item.id);
// 下载成功,从列表中移除
} catch (error) {
// 下载仍然失败,添加回列表
const li = document.createElement('li');
li.textContent = item.id;
failedList.appendChild(li);
}
}, index * 500); // 使用更长的间隔
});
});
// 打包下载所有图标
document.getElementById('downloadZip').addEventListener('click', function() {
if (iconData.length === 0) {
alert('没有找到图标');
return;
}
const statusBar = document.getElementById('statusBar');
const progressBar = document.getElementById('progressBar');
const statusText = document.getElementById('statusText');
// 显示状态栏
statusBar.style.display = 'block';
failedIcons.style.display = 'none';
statusText.textContent = '正在创建ZIP文件...';
progressBar.style.width = '0%';
progressBar.textContent = '0%';
// 创建一个新的JSZip实例
const zip = new JSZip();
let completed = 0;
const total = iconData.length;
// 添加所有SVG到zip
iconData.forEach(item => {
// 去掉文件名中的'icon-'前缀
const cleanFileName = item.id.replace(/^icon-/, '');
zip.file(`${cleanFileName}.svg`, item.svg);
completed++;
// 更新进度
const progress = Math.floor((completed / total) * 100);
progressBar.style.width = `${progress}%`;
progressBar.textContent = `${progress}%`;
});
// 生成zip文件并下载
statusText.textContent = '正在生成ZIP文件...';
zip.generateAsync({ type: 'blob' })
.then(function(content) {
// 下载zip文件
const url = URL.createObjectURL(content);
const a = document.createElement('a');
a.href = url;
a.download = 'svg-icons.zip';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
statusText.textContent = '下载完成!';
progressBar.style.width = '100%';
progressBar.textContent = '100%';
})
.catch(function(error) {
statusText.textContent = '创建ZIP文件失败: ' + error.message;
console.error('创建ZIP文件失败:', error);
});
});
// 下载SVG文件
function downloadSvg(svgContent, fileName) {
// 去掉文件名中的'icon-'前缀
const cleanFileName = fileName.replace(/^icon-/, '');
const blob = new Blob([svgContent], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${cleanFileName}.svg`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
});
</script>
</body>
</html>