Spring Boot 2.7.2, Java/JDK 18, PostgreSQL 14, Excel XLSX file. Java code
package com.example.controller;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.io.InputStream;
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/download")
public class DownloadController {
private static final Logger LOGGER = LoggerFactory.getLogger(DownloadController.class);
// GET http://localhost:80/download/B01-DN_01_Summary.xlsx
// E:\github\spring_jwt\src\main\resources\FilesHere\ImportExcel\B01-DN_01_Summary.xlsx
@GetMapping("/{file_name}")
public HttpEntity<ByteArrayResource> createExcelWithTaskConfigurations(@PathVariable("file_name") String file_name) throws IOException {
InputStream inputStream = getClass().getResourceAsStream("/FilesHere/ImportExcel/" file_name);
byte[] excelContent = IOUtils.toByteArray(inputStream);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" file_name);
httpHeaders.setContentType(MediaType.parseMediaType("application/vnd.ms-excel"));
return new HttpEntity<>(new ByteArrayResource(excelContent), httpHeaders);
}
}
React 18.2.0
import React from 'react';
import DataGrid, {Column, Pager, Paging, FilterRow, Lookup} from 'devextreme-react/data-grid';
import apiClient from "../../http-common";
import {Link} from "react-router-dom";
import Button from "devextreme-react/button";
export default function Import_excel() {
const [dataSource, setDataSource] = React.useState([]);
// React.useEffect(() => {
// async function getData(file) {
// const bearer_token = `Bearer ${localStorage.getItem('token')}`;
// try {
// const config = {
// headers: {
// Authorization: bearer_token
// }
// };
// const res = await apiClient.get('/download/' file, config); // <== Here we use await keywords to get the result of the Promise, check internet if it's blurry for you
// // setDataSource(res.data); // Maybe do some work on res.data to get the expected format
// // console.log(res.data)
// } catch (err) {
// // here display a message to the user or something else
// // console.error(err.message);
// }
// }
// }, []);
const dataSource2 = {
store: {
type: "array",
key: "file",
data: [{
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Nhóm Khách hàng, nhà cung cấp",
"file": "Mau_danh_muc_nhom_KH_NCC.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Khách hàng",
"file": "Mau_danh_muc_khach_hang.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Nhà cung cấp",
"file": "Mau_danh_muc_nha_cung_cap.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Nhân viên",
"file": "Mau_danh_muc_nhan_vien.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Nhóm vật tư, hàng hóa, dịch vụ",
"file": "Mau_danh_muc_nhom_VTHH.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Vật tư, hàng hóa",
"file": "Danh_muc_VTHH_cap_nhat_gia_nhap_kho.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Đối tượng Tập hợp chi phí",
"file": "Mau_danh_muc_doi_tuong_THCP.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Công trình",
"file": "Mau_danh_muc_cong_trinh.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Mã thống kê",
"file": "Mau_danh_muc_ma_thong_ke.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Cơ cấu tổ chức",
"file": "Mau_danh_muc_co_cau_to_chuc.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Kho",
"file": "Mau_danh_muc_kho.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Khoản mục chi phí",
"file": "Mau_danh_muc_khoan_muc_chi_phi.xlsx"
}, {
"group": "Dữ liệu Danh mục",
"sub_group": "",
"name": "Mục thu/chi",
"file": "Mau_danh_muc_muc_thu_chi.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Số dư Tài khoản Kế toán",
"file": "So_du_tai_khoan.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Số dư Tài khoản Ngân hàng",
"file": "So_du_tai_khoan_ngan_hang_VND.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Công nợ Khách hàng",
"file": "Cong_no_dau_ky_khach_hang.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Công nợ Nhà cung cấp",
"file": "03_So_du_cong_no_nha_cung_cap.xls"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Công nợ Nhân viên",
"file": "04_So_du_cong_no_nhan_vien.xls"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Tồn kho vật tư, hàng hóa",
"file": "nv.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Chi phí dở dang theo Đối tượng tập hợp chi phí",
"file": "nv.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Chi phí dở dang theo Công trình",
"file": "Chi_phi_do_dang_cong_trinh.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Chi phí dở dang theo Đơn đặt hàng",
"file": "Chi_phi_do_dang_don_hang.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Chi phí dở dang theo Hợp đồng bán",
"file": "Chi_phi_do_dang_hop_dong.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Khai báo Tài sản cố định đầu kỳ",
"file": "nv.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Khai báo CCDC đầu kỳ",
"file": "06_Cong_cu_dung_cu_dau_ky.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Doanh thu nhận trước đầu kỳ",
"file": "nv.xlsx"
}, {
"group": "Số dư",
"sub_group": "",
"name": "Chi phí trả trước đầu kỳ",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Quỹ",
"name": "Phiếu thu",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Quỹ",
"name": "Phiếu chi",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Ngân hàng",
"name": "Thu tiền gửi",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Ngân hàng",
"name": "Chi tiền gửi",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Ngân hàng",
"name": "Chuyển tiền nội bộ",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Khế ước vay",
"name": "Hợp đồng tín dụng",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Khế ước vay",
"name": "Khế ước vay",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Khế ước vay",
"name": "Khế ước vay đầu kỳ",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Đơn mua hàng",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Hợp đồng mua hàng",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Mua hàng qua kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Mua hàng không qua kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Mua hàng nhiều hóa đơn qua kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Mua hàng nhiều hóa đơn không qua kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Mua dịch vụ",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Mua hàng trả lại qua kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Hàng mua trả lại không qua kho",
"file": "Tra_lai_hang_mua_khong_qua_kho.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mua hàng",
"name": "Hàng mua giảm giá",
"file": "Hang_mua_giam_gia_VND.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Bán hàng",
"name": "Báo giá",
"file": "Bao_gia.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Bán hàng",
"name": "Đơn đặt hàng",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Bán hàng",
"name": "Bán hàng",
"file": "Ban_hang_VND.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Bán hàng",
"name": "Hóa đơn bán hàng",
"file": "Hoa_don_ban_hang_VND.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Bán hàng",
"name": "Hàng bán trả lại",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Bán hàng",
"name": "Hàng bán giảm giá",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Bán hàng",
"name": "Doanh thu nhận trước đầu kỳ",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Bán hàng",
"name": "Danh thu nhận trước",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Kho",
"name": "Chuyển kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Kho",
"name": "Nhập kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Kho",
"name": "Xuất kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Kho",
"name": "Lệnh sản xuất",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Kho",
"name": "Lắp ráp, tháo dỡ",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Công cụ, dụng cụ",
"name": "Ghi tăng",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Tài sản cố định",
"name": "Ghi tăng",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Giá thành",
"name": "Định mức nguyên vật liệu công trình",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Giá thành",
"name": "Định mức giá thành phẩm",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Giá thành",
"name": "Định mức phân bổ theo đối tượng THCP",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Giá thành",
"name": "Định mức phân bổ theo công trình",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Tổng hợp",
"name": "Chứng từ ngiệp vụ khác",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Tổng hợp",
"name": "Chứng từ quyết toán tạm ứng",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Tổng hợp",
"name": "Chi phí trả trước đầu kỳ",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Tổng hợp",
"name": "Chi phí trả trước",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Hợp đồng",
"name": "Hợp đồng bán",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mã quy cách",
"name": "Nhập khẩu mã quy cách cho chứng từ nhập kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mã quy cách",
"name": "Nhập khẩu mã quy cách cho chứng từ bán hàng, xuất kho",
"file": "nv.xlsx"
}, {
"group": "Chứng từ",
"sub_group": "Mã quy cách",
"name": "Nhập khẩu mã quy cách cho chứng từ chuyển kho",
"file": "nv.xlsx"
}
]
}
};
async function getData(file) {
const bearer_token = `Bearer ${localStorage.getItem('token')}`;
try {
const config = {
headers: {
Authorization: bearer_token
}
};
const res = await apiClient.get('/download/' file, config); // <== Here we use await keywords to get the result of the Promise, check internet if it's blurry for you
// setDataSource(res.data); // Maybe do some work on res.data to get the expected format
// console.log(res.data)
} catch (err) {
// here display a message to the user or something else
// console.error(err.message);
}
}
function DiffCell(cellData) {
return (
<Button onClick={() => {
console.log("he>>>")
console.log(cellData.data.file)
getData(cellData.data.file).then(r => r)
}}
>Tải về</Button>
);
}
return (
<React.Fragment>
<h2 className={'content-block'}>Nhập dữ liệu từ Excel</h2>
<DataGrid className={'dx-card wide-card'} dataSource={dataSource2}
showBorders={true}
showColumnLines={true}
allowColumnResizing={true}
allowColumnReordering={true}
focusedRowEnabled={true}
defaultFocusedRowIndex={0}
columnAutoWidth={true}
columnHidingEnabled={true}>
<Paging defaultPageSize={100}/>
<Pager showPageSizeSelector={true} showInfo={true}/>
<FilterRow visible={true}/>
<Column dataField={'group'} name={'group'} width={290} caption={'Nhóm dữ liệu'} dataType="string"
allowSorting={true} hidingPriority={1} groupIndex={0}/>
<Column dataField={'sub_group'} name={'sub_group'} width={290} caption={'Nhóm con'} dataType="string"
allowSorting={true} hidingPriority={1} groupIndex={1}/>
<Column dataField={'name'} name={'name'} width={200} caption={'Tên'} dataType="string"
allowSorting={true} hidingPriority={8}/>
<Column width={190} caption={'Tải về'} cellRender={DiffCell}>
</Column>
</DataGrid>
</React.Fragment>
)
}
Spring RESTful Spring: Return 200, but cannot download, how to fix?
CodePudding user response:
I think you should add produces = MediaType.APPLICATION_OCTET_STREAM_VALUE
to @GetMapping
annotation. If this doesn't help then try to return ByteArrayResource
directly instead of wrapping it with HttpEntity
.
P.S. When I was implementing a similar controller for file downloading I did it like
@GetMapping(path = "/downloadTranslatedFile/{translatedFileId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public Resource downloadFile(@PathVariable("translatedFileId") long translatedFileId) {
TranslatedFileEntity file = translatedFileRepository.findById(translatedFileId).orElseThrow(NullPointerException::new);
return readFromFile(file);
}
private ByteArrayResource readFromFile(TranslatedFileEntity file) {
return new ByteArrayResource(file.getData());
}
CodePudding user response:
By the looks of this, you're downloading the file using fetch, Axios or whatever, but not sure as you haven't included the HTTP client code.
When the response has been received, you need to use a package like File Saver to actually save the file, otherwise the data will simply be disregarded.
You should also ensure that the correct headers are on the response:
- Content-Disposition: "attachment;filename=report.xls"
- Content-Type: "application/octet-stream"
If using Axios, you should also set responseType: 'blob'
as part of the request options, to ensure the data is downloaded as a Blob rather than JSON.
Using file-saver
, you can also use this to download the file directly, if no security headers are required to download said file.