亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

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

什么是StreamReader

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

StreamReader的主要功能

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

StreamReader的優(yōu)勢

簡化了文件讀取的過程,提供了高層次的讀取方法可以處理不同類型的文件,如文本文件、CSV文件等

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

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

        Sheet sheet = wk.getSheetAt(0);
        //遍歷所有的行
        for (Row row : sheet) {
            System.out.println("開始遍歷第" + 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 {
		// 開始時間
    	Long begin = new Date().getTime();
    	// excel轉(zhuǎn)換為List集合(約30s~40s)
		List<TpInstallationMaintenanceLabelDetailed> tpInstallationMaintenanceLabelDetailedList = largeFilesUtils.importExcelLargeFile(file, updateSupport);
		// 結(jié)束時間
        Long end = new Date().getTime();
        // 數(shù)據(jù)導(dǎo)入(約30s)
		String message = importInstallationMaintenanceLabelDetailed(tpInstallationMaintenanceLabelDetailedList, updateSupport);
		// 總用時(約60s~70s)
		message = message +"<br/>數(shù)據(jù)轉(zhuǎn)換花費(fèi)時間 : "+(end - begin) / 1000 + " s" ;
		// 返回
		return AjaxResult.success(message);
	}

2、Excel數(shù)據(jù)轉(zhuǎn)為List

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 {
			// 大文件測試開始
			InputStream inputStream = file.getInputStream();
			// com.monitorjbl.xlsx.StreamingReader 
			Workbook workbook = StreamingReader.builder().rowCacheSize(1000) // 緩存到內(nèi)存中的行數(shù)(默認(rèn)是10)
					.bufferSize(10240) // 讀取資源時,緩存到內(nèi)存的字節(jié)大小(默認(rèn)是1024)
					.open(inputStream);
			// 獲取第一個Shhet
			Sheet sheet = workbook.getSheetAt(0);
			//
			boolean fastRowBoolean = true;
			// monitorjbl只能支持遍歷,不能通過指定下標(biāo)獲取
	        for (Row row : sheet) {
	        	// 判斷是否首行
	        	if(fastRowBoolean) {
	        		// 設(shè)置為非首行
	        		fastRowBoolean = false;
	        		// continue 語句用于跳過當(dāng)前循環(huán)中剩余的代碼,并開始下一次迭代。
	        		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í)行開始時間
    	Long begin = new Date().getTime();
        // 線程數(shù)
        final int THREAD_COUNT = 10;
        // 每個線程處理的數(shù)據(jù)量
        final int BATCH_SIZE = tpInstallationMaintenanceLabelDetailedList.size() / THREAD_COUNT;
        // ExecutorService是Java中對線程池定義的一個接口
        ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
        // 
        for (int i = 0; i < THREAD_COUNT; i++) {
        	// List數(shù)據(jù)開始下標(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ù)庫連接對象
                    Connection conn = null;
                    // 初始化預(yù)編譯的 SQL 語句的對象
                    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è)置自動提交模式,默認(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ù)編譯對象
                        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í)行語句
                        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ù)庫連接
                                conn.close();
                            } catch (SQLException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            });
        }
        //關(guān)閉線程池,不接受新任務(wù),但會把已添加的任務(wù)執(zhí)行完
        executor.shutdown();
        // 等待所有線程完成任務(wù)
        while (!executor.isTerminated()) {} 
        System.out.println("完成");
    	// 結(jié)束時間
        Long end = new Date().getTime();
        // 耗時
        logger.debug(tpInstallationMaintenanceLabelDetailedList.size()+"條數(shù)據(jù)插入花費(fèi)時間 : " + (end - begin) / 1000 + " s");
        //
    	return "數(shù)據(jù)導(dǎo)入成功!共 " + tpInstallationMaintenanceLabelDetailedList.size() + " 條!"+"<br/>數(shù)據(jù)導(dǎo)入花費(fèi)時間 : "+(end - begin) / 1000 + " s" ;
    }

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

相關(guān)文章

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

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

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

    Spring?Boot開發(fā)時Java對象和Json對象之間的轉(zhuǎn)換

    在Spring?Boot開發(fā)中,我們經(jīng)常需要處理Java對象和Json對象之間的轉(zhuǎn)換,本文將介紹如何在Spring?Boot項(xiàng)目中實(shí)現(xiàn)Java對象和Json對象之間的轉(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í)例代碼,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • springboot @Configuration和@Componment的區(qū)別及說明

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

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

    springboot中使用@NotNull注解無效解決方法

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

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

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

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

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

    如何利用Java爬蟲獲取蘇寧易購商品詳情

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

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

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

最新評論