欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)Excel百萬(wàn)級(jí)數(shù)據(jù)導(dǎo)入功能的示例代碼

 更新時(shí)間:2024年04月09日 09:01:56   作者:Crhy、Y  
這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)Excel百萬(wàn)級(jí)數(shù)據(jù)導(dǎo)入功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下

前言

在遇到大數(shù)據(jù)量excel,50MB大小或數(shù)百萬(wàn)級(jí)別的數(shù)據(jù)讀取時(shí),使用常用的POI容易導(dǎo)致讀取時(shí)內(nèi)存溢出或者cpu飆升。
本文討論的是針對(duì)xlsx格式的excel文件上傳,采用com.monitorjbl.xlsx.StreamingReader 。

什么是StreamReader

StreamReader 是 java.io 包中的一個(gè)類(lèi),用于讀取字符流的高級(jí)類(lèi)。它繼承自 Reader 類(lèi),可以以字符為單位讀取文件中的數(shù)據(jù)。

StreamReader的主要功能

  • 以字符為單位讀取文件中的數(shù)據(jù)
  • 提供了多種讀取方法,如read()、readLine()等
  • 可以指定字符編碼,以適應(yīng)不同類(lèi)型的文件

StreamReader的優(yōu)勢(shì)

簡(jiǎn)化了文件讀取的過(guò)程,提供了高層次的讀取方法可以處理不同類(lèi)型的文件,如文本文件、CSV文件等

可以讀取大型文件,節(jié)省內(nèi)存空間

注:StreamReader只能用遍歷形式讀取數(shù)據(jù)

        Sheet sheet = wk.getSheetAt(0);
        //遍歷所有的行
        for (Row row : sheet) {
            System.out.println("開(kāi)始遍歷第" + row.getRowNum() + "行數(shù)據(jù):");
            //遍歷所有的列
            for (Cell cell : row) {
                System.out.print(cell.getStringCellValue() + " ");
            }
            System.out.println(" ");
        }

案例步驟

1、導(dǎo)入文件前端接口

Controller.java

    /**
	 * 導(dǎo)入文件前端接口
	 */
	@PostMapping("/importData")
	@ResponseBody
	public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
		// 開(kāi)始時(shí)間
    	Long begin = new Date().getTime();
    	// excel轉(zhuǎn)換為L(zhǎng)ist集合(約30s~40s)
		List<TpInstallationMaintenanceLabelDetailed> tpInstallationMaintenanceLabelDetailedList = largeFilesUtils.importExcelLargeFile(file, updateSupport);
		// 結(jié)束時(shí)間
        Long end = new Date().getTime();
        // 數(shù)據(jù)導(dǎo)入(約30s)
		String message = importInstallationMaintenanceLabelDetailed(tpInstallationMaintenanceLabelDetailedList, updateSupport);
		// 總用時(shí)(約60s~70s)
		message = message +"<br/>數(shù)據(jù)轉(zhuǎn)換花費(fèi)時(shí)間 : "+(end - begin) / 1000 + " s" ;
		// 返回
		return AjaxResult.success(message);
	}

2、Excel數(shù)據(jù)轉(zhuǎn)為L(zhǎng)ist

largeFilesUtils.java

 
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
 
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
 
import com.monitorjbl.xlsx.StreamingReader;
import com.ruoyi.huawei.domain.TpInstallationMaintenanceLabelDetailed;
 
 
/**
 * 大文件Excel導(dǎo)入
 * 
 * @author y
 * @date 2024-03-29
 */
@Service
public class LargeFilesUtils {
 
	/**
	 * 大文件Excel導(dǎo)入
	 * 
	 * @param
	 * @return 工具
	 */
	public List<TpInstallationMaintenanceLabelDetailed> importExcelLargeFile(MultipartFile file,
			boolean updateSupport) {
 
		List<TpInstallationMaintenanceLabelDetailed> tpInstallationMaintenanceLabelDetailedList = new ArrayList<TpInstallationMaintenanceLabelDetailed>();
		try {
			// 大文件測(cè)試開(kāi)始
			InputStream inputStream = file.getInputStream();
			// com.monitorjbl.xlsx.StreamingReader 
			Workbook workbook = StreamingReader.builder().rowCacheSize(1000) // 緩存到內(nèi)存中的行數(shù)(默認(rèn)是10)
					.bufferSize(10240) // 讀取資源時(shí),緩存到內(nèi)存的字節(jié)大小(默認(rèn)是1024)
					.open(inputStream);
			// 獲取第一個(gè)Shhet
			Sheet sheet = workbook.getSheetAt(0);
			//
			boolean fastRowBoolean = true;
			// monitorjbl只能支持遍歷,不能通過(guò)指定下標(biāo)獲取
	        for (Row row : sheet) {
	        	// 判斷是否首行
	        	if(fastRowBoolean) {
	        		// 設(shè)置為非首行
	        		fastRowBoolean = false;
	        		// continue 語(yǔ)句用于跳過(guò)當(dāng)前循環(huán)中剩余的代碼,并開(kāi)始下一次迭代。
	        		continue;
	        	}
	        	// 創(chuàng)建實(shí)體
				TpInstallationMaintenanceLabelDetailed rowData = new TpInstallationMaintenanceLabelDetailed();
	        	// 列下標(biāo)初始化
	            int n = 0;
	            // 遍歷列
	            for (Cell cell : row) {
	            	//
					switch (n) {
                    // 第一列
					case 0:
						rowData.setPppoeAccount(cell.getStringCellValue());
						break;
                    // 第二列
					case 1:
						rowData.setInstallationMaintenanceName(cell.getStringCellValue());
						break;
					case 2:
						rowData.setCounty(cell.getStringCellValue());
						break;
					case 3:
						rowData.setPoorQualityUser(cell.getStringCellValue());
						break;
					case 4:
						rowData.setOldLightCat(cell.getStringCellValue());
						break;
					case 5:
						rowData.setSetTopBoxWirelessConnection(cell.getStringCellValue());
						break;
					case 6:
						rowData.setPleaseUseXgponOnu(cell.getStringCellValue());
						break;
					case 7:
						rowData.setHighTemperatureLightCat(cell.getStringCellValue());
						break;
					case 8:
						rowData.setAnOldSetTopBox(cell.getStringCellValue());
						break;
					case 9:
						rowData.setTwoOldSetTopBoxes(cell.getStringCellValue());
						break;
					case 10:
						rowData.setThreeOldSetTopBoxes(cell.getStringCellValue());
						break;
					case 11:
						rowData.setAnPoorQualityRouter(cell.getStringCellValue());
						break;
					case 12:
						rowData.setTwoPoorQualityRouters(cell.getStringCellValue());
						break;
					case 13:
						rowData.setThreePoorQualityRouters(cell.getStringCellValue());
						break;
					case 14:
						rowData.setThreeOrMoreLowQualityRouters(cell.getStringCellValue());
						break;
					case 15:
						rowData.setThreeOrMoreOldSetTopBoxes(cell.getStringCellValue());
						break;
					case 16:
						rowData.setSeverelyPoorQualityUsersAndOldOpticalCats(cell.getStringCellValue());
						break;
					// 處理其他屬性
					default:
						break;
 
					}
					// 列下標(biāo)+1
					n = n+1;
	            }
	            tpInstallationMaintenanceLabelDetailedList.add(rowData);
	        }
	        workbook.close();
 
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}
		
		return tpInstallationMaintenanceLabelDetailedList;
	}
 
}

3、List集合數(shù)據(jù)導(dǎo)入

importInstallationMaintenanceLabelDetailed

/**
     * 導(dǎo)入文件分析
     */
    public String importInstallationMaintenanceLabelDetailed(List<TpInstallationMaintenanceLabelDetailed> tpInstallationMaintenanceLabelDetailedList, Boolean isUpdateSupport)
    {
        if (StringUtils.isNull(tpInstallationMaintenanceLabelDetailedList) || tpInstallationMaintenanceLabelDetailedList.size() == 0)
        {
            throw new ServiceException("導(dǎo)入數(shù)據(jù)不能為空!");
        }
        // 執(zhí)行開(kāi)始時(shí)間
    	Long begin = new Date().getTime();
        // 線程數(shù)
        final int THREAD_COUNT = 10;
        // 每個(gè)線程處理的數(shù)據(jù)量
        final int BATCH_SIZE = tpInstallationMaintenanceLabelDetailedList.size() / THREAD_COUNT;
        // ExecutorService是Java中對(duì)線程池定義的一個(gè)接口
        ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
        // 
        for (int i = 0; i < THREAD_COUNT; i++) {
        	// List數(shù)據(jù)開(kāi)始下標(biāo)
            final int startIndex = i * BATCH_SIZE;
            // List數(shù)據(jù)結(jié)束下標(biāo)
            final int endIndex = (i + 1) * BATCH_SIZE;
            // 線程池執(zhí)行
            executor.submit(new Runnable() {
                public void run() {
                	// 初始化數(shù)據(jù)庫(kù)連接對(duì)象
                    Connection conn = null;
                    // 初始化預(yù)編譯的 SQL 語(yǔ)句的對(duì)象
                    PreparedStatement ps = null;
         
                    try {
                        // 獲取連接
                		conn =  DriverManager.getConnection("jdbc:mysql://localhost:3306/tool_platform_db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&useSSL=false", "root", "123456");//獲取連接
                        // 設(shè)置自動(dòng)提交模式,默認(rèn)true
                        conn.setAutoCommit(false);
                        // sql前綴
                        String prefix = "INSERT INTO tp_label_detailed ("
                        		+ "account,"
                        		+ "maintenance_name,"
                        		+ "county,quality_user,"
                        		+ "light_cat,wireless_connection,"
                        		+ "xgpon_onu,"
                        		+ "light_cat,"
                        		+ "an_box,two_boxes,"
                        		+ "three_boxes,"
                        		+ "an_router,"
                        		+ "two_routers,"
                        		+ "three_routers,"
                        		+ "three_or_more_routers,"
                        		+ "three_or_more_boxes,"
                        		+ "severely_and_cats"
                        		+ ") VALUES ";
                        // 創(chuàng)建預(yù)編譯對(duì)象
                        ps = conn.prepareStatement(prefix);
                        // 保存sql后綴
                        StringBuffer suffix = new StringBuffer();
                        // 執(zhí)行條數(shù)
                        int number_of_cycles = 0;
                        //
                        for (int j = startIndex; j < endIndex; j++) {
                        	// 拼接sql
                    		suffix.append("("+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getPppoeAccount()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getInstallationMaintenanceName()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getCounty()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getPoorQualityUser()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getOldLightCat()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getSetTopBoxWirelessConnection()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getPleaseUseXgponOnu()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getHighTemperatureLightCat()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getAnOldSetTopBox()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getTwoOldSetTopBoxes()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getThreeOldSetTopBoxes()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getAnPoorQualityRouter()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getTwoPoorQualityRouters()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getThreePoorQualityRouters()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getThreeOrMoreLowQualityRouters()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getThreeOrMoreOldSetTopBoxes()+"',"+
                    				"'"+tpInstallationMaintenanceLabelDetailedList.get(j).getSeverelyPoorQualityUsersAndOldOpticalCats()+"'"+
                    				"),");   //拼接sql
                    		number_of_cycles = number_of_cycles +1;
                    		
                        }
                        // sql拼接
                		String sql = prefix + suffix.substring(0, suffix.length() - 1);
                		// 添加預(yù)處理sql
                        ps.addBatch(sql);
                        // 執(zhí)行語(yǔ)句
                        ps.executeBatch();
                        // 提交
                        conn.commit();
                        // 初始化拼接sql
                        suffix.setLength(0);
                        // 初始化條數(shù)
                        number_of_cycles = 1;
 
                    } catch (SQLException e) {
                        e.printStackTrace();
                    } finally {
                        if (ps != null) {
                            try {
                            	// 關(guān)閉ps
                                ps.close();
                            } catch (SQLException e) {
                                e.printStackTrace();
                            }
                        }
         
                        if (conn != null) {
                            try {
                            	// 關(guān)閉數(shù)據(jù)庫(kù)連接
                                conn.close();
                            } catch (SQLException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            });
        }
        //關(guān)閉線程池,不接受新任務(wù),但會(huì)把已添加的任務(wù)執(zhí)行完
        executor.shutdown();
        // 等待所有線程完成任務(wù)
        while (!executor.isTerminated()) {} 
        System.out.println("完成");
    	// 結(jié)束時(shí)間
        Long end = new Date().getTime();
        // 耗時(shí)
        logger.debug(tpInstallationMaintenanceLabelDetailedList.size()+"條數(shù)據(jù)插入花費(fèi)時(shí)間 : " + (end - begin) / 1000 + " s");
        //
    	return "數(shù)據(jù)導(dǎo)入成功!共 " + tpInstallationMaintenanceLabelDetailedList.size() + " 條!"+"<br/>數(shù)據(jù)導(dǎo)入花費(fèi)時(shí)間 : "+(end - begin) / 1000 + " s" ;
    }

到此這篇關(guān)于Java實(shí)現(xiàn)Excel百萬(wàn)級(jí)數(shù)據(jù)導(dǎo)入功能的示例代碼的文章就介紹到這了,更多相關(guān)Java百萬(wàn)級(jí)數(shù)據(jù)導(dǎo)入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解在Java程序中運(yùn)用Redis緩存對(duì)象的方法

    詳解在Java程序中運(yùn)用Redis緩存對(duì)象的方法

    這篇文章主要介紹了在Java程序中運(yùn)用Redis緩存對(duì)象的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Spring?Boot開(kāi)發(fā)時(shí)Java對(duì)象和Json對(duì)象之間的轉(zhuǎn)換

    Spring?Boot開(kāi)發(fā)時(shí)Java對(duì)象和Json對(duì)象之間的轉(zhuǎn)換

    在Spring?Boot開(kāi)發(fā)中,我們經(jīng)常需要處理Java對(duì)象和Json對(duì)象之間的轉(zhuǎn)換,本文將介紹如何在Spring?Boot項(xiàng)目中實(shí)現(xiàn)Java對(duì)象和Json對(duì)象之間的轉(zhuǎn)換,感興趣的朋友跟隨小編一起看看吧
    2023-09-09
  • java中javamail發(fā)送帶附件的郵件實(shí)現(xiàn)方法

    java中javamail發(fā)送帶附件的郵件實(shí)現(xiàn)方法

    這篇文章主要介紹了java中javamail發(fā)送帶附件的郵件實(shí)現(xiàn)方法,較為詳細(xì)的分析了JavaMail發(fā)送郵件的用法,是非常實(shí)用的技巧,需要的朋友可以參考下
    2015-01-01
  • springboot 使用ThreadLocal的實(shí)例代碼

    springboot 使用ThreadLocal的實(shí)例代碼

    這篇文章主要介紹了springboot 使用ThreadLocal的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • springboot @Configuration和@Componment的區(qū)別及說(shuō)明

    springboot @Configuration和@Componment的區(qū)別及說(shuō)明

    這篇文章主要介紹了springboot @Configuration和@Componment的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • springboot中使用@NotNull注解無(wú)效解決方法

    springboot中使用@NotNull注解無(wú)效解決方法

    這篇文章主要給大家介紹了關(guān)于springboot中使用@NotNull注解無(wú)效的解決方法,進(jìn)行參數(shù)校驗(yàn)的時(shí)候,加了@NotNull注解,@Validated注解和@Valid注解,但是參數(shù)校驗(yàn)的時(shí)候不生效,需要的朋友可以參考下
    2023-08-08
  • Java實(shí)現(xiàn)默認(rèn)目錄查看與修改的方法

    Java實(shí)現(xiàn)默認(rèn)目錄查看與修改的方法

    本項(xiàng)目介紹了Java如何獲取和修改默認(rèn)目錄,并通過(guò)示例代碼展示了如何在默認(rèn)目錄下創(chuàng)建和操作文件,盡管Java無(wú)法直接更改全局默認(rèn)目錄,但可以通過(guò)System.setProperty間接影響部分API的默認(rèn)行為,需要的朋友可以參考下
    2025-03-03
  • Java中的getClass()以及getName()方法使用

    Java中的getClass()以及getName()方法使用

    這篇文章主要介紹了Java中的getClass()以及getName()方法使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 如何利用Java爬蟲(chóng)獲取蘇寧易購(gòu)商品詳情

    如何利用Java爬蟲(chóng)獲取蘇寧易購(gòu)商品詳情

    蘇寧易購(gòu)作為中國(guó)領(lǐng)先的電商平臺(tái)之一,提供了豐富的商品信息,本文將介紹如何使用Java語(yǔ)言開(kāi)發(fā)爬蟲(chóng),獲取蘇寧易購(gòu)商品的詳細(xì)信息,感興趣的朋友一起看看吧
    2024-12-12
  • 基于Java實(shí)現(xiàn)經(jīng)典蜘蛛紙牌游戲

    基于Java實(shí)現(xiàn)經(jīng)典蜘蛛紙牌游戲

    《蜘蛛紙牌》(Ancient?Spider)?是由Oberon?Games開(kāi)發(fā)的一款休閑益智類(lèi)游戲。本文將利用Java語(yǔ)言實(shí)現(xiàn)這一經(jīng)典游戲,需要的可以參考一下
    2022-05-05

最新評(píng)論