如何使用AJAX上传大型CSV文件


How to use AJAX to upload large CSV file?

我们有一些包含大量记录的CSV文件。需要将此文件上传到使用web界面的MySQL数据库。这些文件是从不同的现场工作中收集的,并通过web应用程序上传到服务器。web应用程序是使用PHP开发的。

最初记录的数量非常小。但是,现在它变得非常大,用户无法将文件上传到服务器。

问题——

  1. 我们必须等待上传整个文件才能开始处理
  2. 我们可以在上传整个文件后看到数据验证错误。
  3. 默认不支持上传大文件
  4. PHP执行时间有限。

所以,我正在寻找一个解决方案,上传CSV文件内容为块。它将帮助我处理每个请求的少量数据。

我的想法是使用JavaScript从CSV文件读取数据。然后使用AJAX POST这些数据。

希望看到少量数据的数据验证错误,如果需要,请停止执行。

在做了一些关于web的研究之后,我发现HTML5 JavaScript File API对于从本地文件系统读取内容非常有用。我写了一个小脚本,它完美地工作。

在这个例子中,我创建了两个文件——
  1. service.php

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Upload large CSV file</title>
		<style>
			body{font-size:8pt; color:#333}
			#wrap{width:500px; margin:5px auto}
			#responce{height:200px; overflow-y:scroll; border:1px solid #ddd;}
		</style>
	</head>
	<body>
		<div id="wrap">
			<ul id="responce">
				
			</ul><!-- // response -->
			
			<input type="file" id="fileSelected"/>
			<button id="btnUpload">Upload</button>
		</div><!-- // wrap -->
		
		<script
			  src="https://code.jquery.com/jquery-3.1.1.min.js"
			  integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
			  crossorigin="anonymous"></script>
		<script>
			var reader_offset = 0;		//current reader offset position
			var buffer_size = 1024;		//
			var pending_content = '';
			
			/**
			* Read a chunk of data from current offset.
			*/
			function readAndSendChunk()
			{
				var reader = new FileReader();
				var file = $('#fileSelected')[0].files[0];
				reader.onloadend = function(evt){
					
					//check for end of file
					if(evt.loaded == 0) return;
					
					//increse offset value
					reader_offset += evt.loaded;
					
					//check for only complete line
					var last_line_end = evt.target.result.lastIndexOf(''n');
					var content = pending_content + evt.target.result.substring(0, last_line_end);
					
					pending_content = evt.target.result.substring(last_line_end+1, evt.target.result.length);
					
					//upload data
					send(content);
				};
				var blob = file.slice(reader_offset, reader_offset + buffer_size);
				reader.readAsText(blob);
			}
			
			/**
			* Send data to server using AJAX
			*/
			function send(data_chank)
			{
				$.ajax({
					url: "service.php",
					method: 'POST',
					data: data_chank
				}).done(function(response) {
				
					//show responce message received from server
					$( '#responce' ).append( '<li>' + response + '</li>');
					
					//try for next chank
					readAndSendChunk();
				});
			}
			
			/**
			* On page load
			*/
			$(function(){
				$('#btnUpload').click(function(){
					reader_offset = 0;
					pending_content = '';
					readAndSendChunk();
				});
			});
		</script>
	</body>
</html>

service.php

<?php
$content = file_get_contents('php://input');
$lines = explode("'n", $content);
foreach($lines as $line){
    $csv_row = str_getcsv($line);
    //save data into database
    //----
}