这里写自定义目录标题
- [跨平台导出下载导出功能 post请求方式](#跨平台导出下载导出功能 post请求方式)
跨平台导出下载导出功能 post请求方式
js原生、vue导出、react导出、axios ( post请求方式)导出四种方式的demo。
代码片
javascript
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Excel文件导出测试</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
border-radius: 8px;
padding: 30px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
.export-section {
margin-bottom: 30px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 6px;
background-color: #fafafa;
}
.export-section h3 {
margin-top: 0;
color: #555;
border-bottom: 2px solid #007bff;
padding-bottom: 10px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #555;
}
input[type="text"] {
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
box-sizing: border-box;
}
button {
background-color: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin-right: 10px;
transition: background-color 0.3s;
}
button:hover {
background-color: #0056b3;
}
button:disabled {
background-color: #6c757d;
cursor: not-allowed;
}
.status {
margin-top: 10px;
padding: 10px;
border-radius: 4px;
font-size: 14px;
}
.status.success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.status.error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.status.loading {
background-color: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
.code-block {
background-color: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
padding: 15px;
margin-top: 10px;
font-family: 'Courier New', monospace;
font-size: 12px;
overflow-x: auto;
}
</style>
</head>
<body>
<div class="container">
<h1>Excel文件导出测试</h1>
<!-- 原生JavaScript导出 -->
<div class="export-section">
<h3>1. 原生JavaScript导出</h3>
<div class="form-group">
<label>主题代码:</label>
<input type="text" id="native-themeCode" value="74WB4X7E22TK3IR1O0HJ1TRN0">
</div>
<div class="form-group">
<label>名称:</label>
<input type="text" id="native-name" value="">
</div>
<div class="form-group">
<label>作者名称:</label>
<input type="text" id="native-authorName" value="">
</div>
<button onclick="exportWithNativeJS()">导出Excel</button>
<div id="native-status" class="status" style="display: none;"></div>
<div class="code-block">
<strong>实现方式:</strong> 使用原生 fetch API 和 Blob 对象处理文件流
</div>
</div>
<!-- Vue导出 -->
<div class="export-section">
<h3>2. Vue导出</h3>
<div id="vue-app">
<div class="form-group">
<label>主题代码:</label>
<input type="text" v-model="themeCode">
</div>
<div class="form-group">
<label>名称:</label>
<input type="text" v-model="name">
</div>
<div class="form-group">
<label>作者名称:</label>
<input type="text" v-model="authorName">
</div>
<button @click="exportExcel" :disabled="loading">{{ loading ? '导出中...' : '导出Excel' }}</button>
<div v-if="status" :class="['status', status.type]">{{ status.message }}</div>
<div class="code-block">
<strong>实现方式:</strong> 使用 Vue 3 Composition API 和 fetch
</div>
</div>
</div>
<!-- React导出 -->
<div class="export-section">
<h3>3. React导出</h3>
<div id="react-app"></div>
</div>
<!-- Axios导出 -->
<div class="export-section">
<h3>4. Axios导出</h3>
<div class="form-group">
<label>主题代码:</label>
<input type="text" id="axios-themeCode" value="74WB4X7E22TK3IR1O0HJ1TRN0">
</div>
<div class="form-group">
<label>名称:</label>
<input type="text" id="axios-name" value="">
</div>
<div class="form-group">
<label>作者名称:</label>
<input type="text" id="axios-authorName" value="">
</div>
<button onclick="exportWithAxios()">导出Excel</button>
<div id="axios-status" class="status" style="display: none;"></div>
<div class="code-block">
<strong>实现方式:</strong> 使用 Axios 库处理文件流下载
</div>
</div>
</div>
<script>
// 导出接口配置
const EXPORT_URL = 'https://toupiao.coscoshipping.com/api-gateway/jpaas-tggl-server/interface/qywxvote/export';
// 1. 原生JavaScript导出
async function exportWithNativeJS() {
const statusEl = document.getElementById('native-status');
statusEl.style.display = 'block';
statusEl.className = 'status loading';
statusEl.textContent = '正在导出...';
try {
const requestData = {
themeCode: document.getElementById('native-themeCode').value,
name: document.getElementById('native-name').value,
authorName: document.getElementById('native-authorName').value
};
const response = await fetch(EXPORT_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = `导出数据_${new Date().getTime()}.xlsx`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
statusEl.className = 'status success';
statusEl.textContent = '导出成功!';
} catch (error) {
statusEl.className = 'status error';
statusEl.textContent = `导出失败: ${error.message}`;
}
}
// 2. Vue导出
const { createApp, ref } = Vue;
createApp({
setup() {
const themeCode = ref('74WB4X7E22TK3IR1O0HJ1TRN0');
const name = ref('');
const authorName = ref('');
const loading = ref(false);
const status = ref(null);
const exportExcel = async () => {
loading.value = true;
status.value = { type: 'loading', message: '正在导出...' };
try {
const requestData = {
themeCode: themeCode.value,
name: name.value,
authorName: authorName.value
};
const response = await fetch(EXPORT_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = `导出数据_${new Date().getTime()}.xlsx`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
status.value = { type: 'success', message: '导出成功!' };
} catch (error) {
status.value = { type: 'error', message: `导出失败: ${error.message}` };
} finally {
loading.value = false;
}
};
return {
themeCode,
name,
authorName,
loading,
status,
exportExcel
};
}
}).mount('#vue-app');
// 3. React导出
const { useState } = React;
function ReactExport() {
const [themeCode, setThemeCode] = useState('74WB4X7E22TK3IR1O0HJ1TRN0');
const [name, setName] = useState('');
const [authorName, setAuthorName] = useState('');
const [loading, setLoading] = useState(false);
const [status, setStatus] = useState(null);
const exportExcel = async () => {
setLoading(true);
setStatus({ type: 'loading', message: '正在导出...' });
try {
const requestData = {
themeCode: themeCode,
name: name,
authorName: authorName
};
const response = await fetch(EXPORT_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = `导出数据_${new Date().getTime()}.xlsx`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
setStatus({ type: 'success', message: '导出成功!' });
} catch (error) {
setStatus({ type: 'error', message: `导出失败: ${error.message}` });
} finally {
setLoading(false);
}
};
return React.createElement('div', null,
React.createElement('div', { className: 'form-group' },
React.createElement('label', null, '主题代码:'),
React.createElement('input', {
type: 'text',
value: themeCode,
onChange: (e) => setThemeCode(e.target.value)
})
),
React.createElement('div', { className: 'form-group' },
React.createElement('label', null, '名称:'),
React.createElement('input', {
type: 'text',
value: name,
onChange: (e) => setName(e.target.value)
})
),
React.createElement('div', { className: 'form-group' },
React.createElement('label', null, '作者名称:'),
React.createElement('input', {
type: 'text',
value: authorName,
onChange: (e) => setAuthorName(e.target.value)
})
),
React.createElement('button', {
onClick: exportExcel,
disabled: loading
}, loading ? '导出中...' : '导出Excel'),
status && React.createElement('div', {
className: `status ${status.type}`
}, status.message),
React.createElement('div', { className: 'code-block' },
React.createElement('strong', null, '实现方式: '),
'使用 React Hooks 和 fetch'
)
);
}
ReactDOM.render(React.createElement(ReactExport), document.getElementById('react-app'));
// 4. Axios导出
async function exportWithAxios() {
const statusEl = document.getElementById('axios-status');
statusEl.style.display = 'block';
statusEl.className = 'status loading';
statusEl.textContent = '正在导出...';
try {
const requestData = {
themeCode: document.getElementById('axios-themeCode').value,
name: document.getElementById('axios-name').value,
authorName: document.getElementById('axios-authorName').value
};
const response = await axios.post(EXPORT_URL, requestData, {
responseType: 'blob'
});
const url = window.URL.createObjectURL(new Blob([response.data]));
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = `导出数据_${new Date().getTime()}.xlsx`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
statusEl.className = 'status success';
statusEl.textContent = '导出成功!';
} catch (error) {
statusEl.className = 'status error';
statusEl.textContent = `导出失败: ${error.message}`;
}
}
</script>
</body>
</html>