数据表到csv文件

DataTable to csv file

我使用 bootstrap/thymeleaf 创建了一个网页,其中我使用 Ajax 显示了一些数据表。我有导出到 CSV 的按钮,但我需要的是从这个数据表生成一个临时文件,并在数据表已经使用按钮加载数据时获取到我的控制器的路径。

所以我需要一种方法来创建一个新函数,但我真的不知道该怎么做。可能不会再调用我的 sql 存储库,因为表非常大。

JavaScript代码

function mostrarMaticulaEstudiant(data) {

    var url = "/9avaldoval/administracio/cercarMaticulaEstudiant?idEdicio=" + data;
    dataTableMatriculaEstudiant(url);
}

function dataTableMatriculaEstudiant(url) {

    var columns;
    var columnsConfig;
    var columnsFiltres;

    columns = crearColumnesTaulaMatriculaEstudiant();
    //columnsConfig = configurarColumnaBotonsEstudis(columns.length);
    var sorting = [[0, "asc"]];

    var htmlTable = crearTaulaHtmlMatriculaEstudiant(14);

    $('#divTaula').html(htmlTable);


    var table = $('#taulaMatriculaEstudiant').DataTable({
        scrollX: true,
        processing: false,
        ajaxSource: url,
        fnServerData: function(sSource, aoData, fnCallback) {
            aoData = $("#formAdmBlue").serializeArray();
            $.ajax({
                "dataType": 'json',
                "type": "POST",
                "url": sSource,
                "data": aoData,
                "success": fnCallback
            });
        },

        columns: columns,
        columnDefs: columnsConfig,
        sorting: sorting,
        language: {
            "lengthMenu": "Mostra _MENU_ files per pàgina",
            "search": "Filtre: ",
            "zeroRecords": "Sense resultats",
            "info": "Pàgina _PAGE_ de _PAGES_",
            "infoEmpty": "Files no trobades a la cerca",
            "infoFiltered": "(filtrat de _MAX_ files totals)",
            "sProcessing": "<img src='/9avaldoval/img/loading_gear.gif' width='48px' height='48px'>",
            "paginate": {
                "next": "<span class='oi oi-chevron-right'></span>",
                "previous": "<span class='oi oi-chevron-left'></span>"
            }
        },
        dom: "<'row'<'col-sm-12 col-md-4'B><'col-sm-12 col-md-4'l><'col-sm-12 col-md-4'f>>" +
            "<'row'<'col-sm-12'tr>>" +
            "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
        buttons: ['copy', 'excel', 'pdf'],
        error: function() {
            alert("No s'ha pogut obtenir la informació");
        }
    });


}


function crearTaulaHtmlMatriculaEstudiant(numColumnes) {

    var htmlTableOpen = '<table style="width: 100%;" cellpadding="0" cellspacing="0" border="0" class="table table-hover" id="taulaMatriculaEstudiant"><thead>';

    var htmlTableHeaderRow = '<tr>';
    var htmlTh = '<th></th>';
    for (var i = 0; i < numColumnes; i++) {
        htmlTableHeaderRow = htmlTableHeaderRow + htmlTh;
    }
    htmlTableHeaderRow = htmlTableHeaderRow + '</tr>';
    var htmlTableClose = '</thead></table>';
    var htmlTable = htmlTableOpen + htmlTableHeaderRow + htmlTableClose;
    return htmlTable;

}


function crearColumnesTaulaMatriculaEstudiant() {


    var columns = [];
    columns.push({ "sTitle": "IdAssigEdicio", "mData": "IdAssigEdicio", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "IdEdicio", "mData": "IdEdicio", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "IdCodiassigPare", "mData": "IdCodiassigPare", "sWidth": "10%", "className": "text-center", "defaultContent": "" });
    columns.push({ "sTitle": "IdUsuariUPF", "mData": "IdUsuariUPF", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "IdCodiAssigFill", "mData": "IdCodiAssigFill", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "IdAssigFill", "mData": "IdAssigFill", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "EsRepetidor", "mData": "EsRepetidor", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "CodiCentreEstudiant", "mData": "CodiCentreEstudiant", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "CentreEstudiant", "mData": "CentreEstudiant", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "EstudiEstudiant", "mData": "EstudiEstudiant", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "CodiEstudiEstudiantL", "mData": "CodiEstudiEstudiantL", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "DescEstudi_es", "mData": "DescEstudi_es", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "DescEstudi_en", "mData": "DescEstudi_en", "sWidth": "10%", "defaultContent": "" });
    columns.push({ "sTitle": "DescEstudi_ca", "mData": "DescEstudi_ca", "sWidth": "10%", "defaultContent": "" });

    return columns;
}

控制器

@RequestMapping(value = "cercarMaticulaEstudiant", params = "idEdicio")
    public @ResponseBody byte[] cercarMaticulaEstudiant(@RequestParam("idEdicio") String idEdicio, Model model)
            throws UnsupportedEncodingException, ParseException {

        log.debug("***** cercarEdicions AJAX ****");

        byte[] dataTableSource = null;
        List<BlueMatriculaEstudiant> llistaMatriculaEstudiants;

        llistaMatriculaEstudiants = blueMatriculaEstudiantService
                .cercarBlueMatriculaEstudiant(Integer.parseInt(idEdicio));

        dataTableSource = operacionsService.blueMatriculaEstudiantsToJson(llistaMatriculaEstudiants);

        return dataTableSource;
    }

HTML/Bootstrap

<div class="col-lg-12" 
                        style="margin-bottom: 40px;">
                        <br>
                        <div class="card">
                            <h5 class="card-header" th:id="llistat"
                                data-th-text="#{administracio.blue.llistat}"></h5>
                            <div class="card-body">
                                <div class="row"
                                    style="padding-left: 10px; padding-right: 10px;">
                                    <div class="col-md-12">
                                        <div id="divTaula"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

我认为最简单的方法是在客户端使用 JS 创建 csv 文件。

首先,您需要从 DataTabletheir documentation shows it could be done like this:

获取数据
let table = $('#taulaMatriculaEstudiant').DataTable()
 
let data = table
    .rows()
    .data()

现在,csv 格式基本上是一种带有分隔符的文本格式。因此,您需要遍历 data 中的行并合并单元格以分隔文本行,如下所示:

let text = '';
data.map( row => text += row.join( ';' ) + '\n' ) // replace ';' with your preferred CSV separator

那么您只需要创建一个文档并下载即可。为此,我建议使用 filesaver.js:

let blob = new Blob( [text], {type: "text/csv;charset=utf-8"} )
saveAs( blob, 'taulaMatriculaEstudiant.csv' ) // any name with CSV extension

请注意 我从来没有使用过 DataTables,所以我可能对 returns 来自 table 在 .rows().data() 之后(我假设它是 returns 一个数组数组,代表行中的单元格)。大体的做法应该是正确的。

编辑

但是我不建议将数据从浏览器发送到服务器 - 只需在服务器端创建正确的文件即可。例如。像这样:

@Controller // note it's not @RestController
public class CsvController {
    private CommonDataService dataService; // service with your table data logic. Don't forget to add @Service to it

    @GetMapping( "/csv/example" )
    public void exampleCsv( HttpServletResponse response ) throws IOException {
        byte[] processedFile = dataService.getTaulaMatriculaEstudiant(); // prepare your data the same way as your main data controller and create the csv table the way you like it

        ContentDisposition disposition = ContentDisposition.builder( "attachment" )
            .filename( "taulaMatriculaEstudiant.csv", StandardCharsets.UTF_8 )
            .build();
        response.setContentType( "text/csv" );
        response.setHeader( "Cache-Control", "no-cache" );
        response.setHeader( "Expires", "0" );
        response.setHeader( "Pragma", "no-cache" );

        IOUtils.copy( new ByteArrayInputStream( processedFile ), response.getOutputStream() ); // IOUtils from Apache Commons-IO
    } 

    @Autowired
    public void setDataService( CommonDataService dataService ) {
        this.dataService = dataService;
    }
}