根据输入的起始页数打印和导出相应的内容

本文介绍了一种使用模态框输入页数,通过后台分页实现数据批量打印和导出的方法。利用Ajax递归和Promise,实现了从指定页数获取数据并呈现的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.在模态框中输入需要打印或导出的起始页数,配合后台的分页实现打印和导出相关页数的数据

2.用到ajax递归,promise

好啦,上代码

1,js部分

function Work(){
    // // 导出
	// $(".importTable").click(function(){openimportpagemodal()});
	// // 打印
	// $(".printTable").click(function(){openPageModal()})
	// // 打印模态框确定
	// $("#selectPrintPage .modal-footer .confirm").click(function(){getprintpage(this)});
	// // 导出模态框确定
	// $("#selectImportPage .modal-footer .confirm").click(function(){getprintpage(this,99)});

	// 打开打印的模态框
	function openPageModal() {
		$("#selectPrintPage").find(".input-group").find("input").val("");
		$("#selectPrintPage").modal("show");
	}

	// 打开导出模态框
	function openimportpagemodal(){
		// 清空數據
		$("#selectImportPage").find(".input-group").find("input").val("");
		$("#selectImportPage").modal("show");
	}

	// 根据页数获取数据
	function getprintpage(e, type) {
		// var href = work.showWindowHref();
		var startcount = $(e).parent().prev().find("#startcount").val() - 0;
		var endcount = $(e).parent().prev().find("#endcount").val() - 0;
		// var page = (endcount - startcount) + 1;
		var url = sjData();
		var postData={};
		postData.orderBy = "createTime ASC";
		postData.pageNum = startcount;
		postData.pageSize = 14;
		if (type) {
			// var tablehtml = $("#dayinTable").html();
			queryAllTableData(url, postData, startcount, endcount, type);
		} else {
			queryAllTableData(url, postData, startcount, endcount);
		}

	}

	// 查询表格数据
	function queryAllTableData(url, postData, startcount, endcount, type) {
		function queryData() {
			var ajaxArr = [];
			function recurrenceajax(url, postData) {
				var retDataa = [];
				$.ajax({
					type: "post",
					url: url,
					data: postData,
					async: false,
					success: function (retData) {
						if (retData.code == 0) {
							retDataa = retData.data.result;
							return retDataa;
						}
					},
					error: function (retData) {
						console.log(retData.msg);
					}
				})
				return retDataa;
			}
			for (let i = startcount; i <= endcount; i++) {
				postData.pageNum = i;
				$.each(recurrenceajax(url, postData), function (k, v) {ajaxArr.push(v);})
			}
			return new Promise(function (resolve, reject) {
				resolve(ajaxArr);
			})
		}
		queryData().then(function (ajaxArr) {
			// var href = work.showWindowHref();
			var responsearr = ajaxArr;
			var page =((endcount - startcount) + 1) * postData.pageSize;
			if (responsearr.length <= page && responsearr.length > 0) {
				function createTablee(data,url,num,type){
					var html = `
					<tr>
						<th style="text-align:center;font-size:14px;">序号</th>
						<th style="text-align:center;min-width:86px;font-size:14px;">机构名称</th>
						<th style="text-align:center;min-width:86px;font-size:14px;">所属区域</th>
						<th style="text-align:center;min-width:86px;font-size:14px;">状态</th>
						<th style="text-align:center;min-width:86px;font-size:14px;">联系人</th>
						<th style="text-align:center;min-width:86px;font-size:14px;">联系电话</th>
						<th style="text-align:center;min-width:86px;font-size:14px;">机构地址</th>
						
					</tr>
					`
					for(let i=0;i<data.length;i++){
						html += `
							<tr>
							<td style="text-align:center;font-size:14px;">${i + 1}</td>
							<td style="text-align:center;font-size:14px;">${data[i].orgname}</td>
							<td style="text-align:center;font-size:14px;">${data[i].area}</td>
							<td style="text-align:center;font-size:14px;">${data[i].orgstatus == 1 ? "启用" : "停用"}</td>
							<td style="text-align:center;font-size:14px;">${data[i].orgcontact}</td>
							<td style="text-align:center;font-size:14px;">${data[i].contactphone}</td>
							<td style="text-align:center;font-size:14px;">${data[i].orgaddress}</td>
							
						</tr>
						`
					}
					$("#dayinTable").html(html);
					return new Promise(function(resolve,reject){
						resolve();
					})
				}
				createTablee(responsearr, "", "", 99).then(function (data) {
					/**
					 * type物質為打印,優質為導出
					 */
					if (!type) {
						$("#selectPrintPage").modal("hide");
						bdhtml = $("#dayincontent").html();
						//alert(bdhtml);
						sprnstr = "<!--startprint-->";   //开始打印标识字符串有17个字符
						eprnstr = "<!--endprint-->";        //结束打印标识字符串
						prnhtml = bdhtml.substr(bdhtml.indexOf(sprnstr) + 17); //从开始打印标识之后的内容
						prnhtml = prnhtml.substring(0, prnhtml.indexOf(eprnstr));//截取开始标识和结束标识之间的内容
						var iframe = null;
						iframe = document.getElementById("iframe1")
						var iwindow = null;
						var iwindow = iframe.contentWindow;//获取iframe的window对象
						iwindow.document.close();
						iwindow.document.write(prnhtml);
						iwindow.print(); //调用浏览器的打印功能打印指定区域
					} else {
						$("#selectImportPage").modal("hide");
						var tableId = document.getElementById('dayinTable');
						var tableToExcel = (function () {
							var uri = 'data:application/vnd.ms-excel;base64,',
								template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--><meta charset="UTF-8"></head><body><table>{table}</table></body></html>',
								base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) },
								format = function (s, c) {
									return s.replace(/{(\w+)}/g,
										function (m, p) { return c[p]; })
								};
							return function (table, name, filename, downloadid) {
								if (!table.nodeType) table = document.getElementById(table);
								var ctx = { worksheet: name || 'Worksheet', table: table.innerHTML };
								// window.location.href = uri + base64(format(template, ctx));
								var a = document.createElement("a");
								a.href = uri + base64(format(template, ctx));;
								a.download = filename;
								a.click();
							}

						})();
						var name ="索杰机构管理列表";
						tableToExcel(tableId, "", name);
					}

				})
			}
		})

	}
}
$(function(){
    work=new Work();

})

2.html部分

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="bootstrap.css">
    <link rel="stylesheet" href="test.less">
</head>

<body>
    <p class="pull-right button importTable">导出</p>
    <p class="pull-right button printTable">打印</p>
    <!-- border="1" cellpadding="0" cellspacing = "0" -->
    <div id="dayin" style="display: none">
        <div id="dayincontent">
            <!--startprint-->
            <table id="dayinTable" border="1" cellpadding="0" cellspacing="0"></table>
            <!--endprint-->
        </div>
        <iframe id="iframe1"></iframe>
    </div>
    <!-- 選擇打印頁數莫太寬 -->
    <div class="modal fade" tabindex="-1" role="dialog" id="selectPrintPage" data-backdrop="static">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">

                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                            aria-hidden="true"><img src="../../img/customer/closeWorkOrder.png"
                                alt="" /></span></button>
                    <h4 class="modal-title">表格打印</h4>
                </div>
                <div class="modal-body">
                    <div class="form-group has-feedback count">
                        <!-- <label class="control-label col-md-2" for="count">打印页数:</label> -->
                        <div class="input-group col-md-10">

                            <div class="startCount">
                                <label>起始打印页数 : </label>
                                <div class="startDateGroup">
                                    <input type="text" name="" id="startcount" />
                                </div>
                            </div>
                            <hr class="connect" />
                            <div class="endCount">
                                <label>结束打印页数 : </label>
                                <div class="endDateGroup">
                                    <input type="text" name="" id="endcount" />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <!-- onclick="getprintpage(this)" -->
                    <a type="button" class="btn btn-primary confirm">确定</a>
                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                </div>
            </div>

        </div>

    </div>

    <!-- 選擇導出頁數莫太寬 -->
    <div class="modal fade" tabindex="-1" role="dialog" id="selectImportPage" data-backdrop="static">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">

                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                            aria-hidden="true"><img src="../../img/customer/closeWorkOrder.png"
                                alt="" /></span></button>
                    <h4 class="modal-title">表格导出</h4>
                </div>
                <div class="modal-body">
                    <div class="form-group has-feedback count">
                        <!-- <label class="control-label col-md-2" for="count">打印页数:</label> -->
                        <div class="input-group col-md-10">

                            <div class="startCount">
                                <label>起始导出页数</label>
                                <div class="startCountGroup">
                                    <input type="text" name="" id="startcount" />
                                </div>
                            </div>
                            <hr class="connect" />
                            <div class="endCount">
                                <label>结束导出页数</label>
                                <div class="endCountGroup">
                                    <input type="text" name="" id="endcount" />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <!-- onclick="getprintpage(this,99)" -->
                    <a class="btn btn-primary confirm" id="download">确定</a>
                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                </div>
            </div>

        </div>

    </div>
    <script type="text/javascript" src="jquery-3.1.1.js"></script>
    <script type="text/javascript" src="bootstrap.min.js" type="text/javascript"
        charset="utf-8"></script>

    <script src="less.min.js"></script>
    <script src="test.js"></script>
</body>

</html>

3.less部分

// 打印表格的樣式

#selectPrintPage,#selectImportPage{

.modal-dialog {

width: 495px;

height: 167px;

margin-top: 320px;

.modal-content {

width: 495px;

height: 167px;

.modal-header {

width: 100%;

height: 42px;

background:linear-gradient(90deg,rgba(47,172,203,1),rgba(74,190,145,1));

border-radius:2px;

padding: 11px;

h4 {

color: #fff;

font-size: 13px;

}

img{

width: 12px;

}

}

.modal-body {

width: 100%;

height: 76px;

padding: 20px 0 0 53px;

.count {

width: 100%;

label {

height: 38px;

text-align: left;

line-height: 38px;

color: #5C7191;

font-size: 12px;

padding: 0;

}

div {

height: 38px;

.startCount,.endCount{

float: left;

width: 145px;

height: 38px;

& > label{

float: left;

width: 101px;

height: 38px;

text-align: center;

line-height: 38px;

}

& > div{

float: left;

width: 42px;

height: 38px;

background: #ffffff;

border: 1px solid #cedbe1;

border-radius: 5px;

padding: 2px;

input{

width: 100%;

height: 100%;

text-align: center;

line-height: 38px;

padding: 0;

border: none;

outline: none;

}

}

}

.connect{

float: left;

width: 15px;

height: 2px;

margin: 19px 12px 0 22px;

background: #CEDBE1;

clear: none;

}

}

}

}

.modal-footer {

width: 100%;

height: 51px;

border: none;

padding: 10px;

text-align: center;

background:rgba(237,246,250,1);

border-radius:0px 0px 2px 2px;

a:nth-child(1) {

width: 58px;

height: 32px;

background:rgba(53,182,148,1);

border-radius:3px;

color: #fff;

font-size: 12px;

line-height: 20px;

border: none;

}

button:nth-child(2) {

width:58px;

height:32px;

background:rgba(53,120,182,1);

border:1px solid rgba(46,112,174,1);

border-radius:3px;

color: #EBF6F2;

font-size: 12px;

}

}

}

}

}

 

<think>好的,我现在需要解决用户提出的Java导出数据不完整的问题。首先,我得理解用户的具体情况。用户提到参考了几个关于Java导出大量数据到Excel的引用,尤其是涉及内存溢出分页处理的问题。因此,可能用户在使用POI导出大量数据时遇到了数据不完整的情况,比如部分数据丢失或文件损坏。 接下来,我需要分析可能导致数据不完整的常见原因。根据引用[2][3],内存溢出是一个大问题,当数据量太大时,如果一次性加载到内存中,可能导致JVM崩溃,从而无法完整导出。此外,分页查询处理不当也可能导致数据遗漏,比如分页逻辑错误或者未正确关闭资源。另外,网络问题或导出过程中断也可能导致文件不完整。 然后,我需要参考提供的解决方案。引用[2]提到使用分多个Excel文件导出,引用[3][4]讨论了分页查询优化使用流式处理,如SXSSFWorkbook来减少内存占用。因此,可能的解决方向包括:优化SQL查询,分批次处理数据,使用流式API,确保资源正确关闭,以及处理网络中断的情况。 接下来,我要组织这些思路,形成结构化的解决方案。首先分批次处理数据,避免内存不足。使用POI的SXSSFWorkbook,设置合适的窗口大小,及时flushdispose。然后检查分页查询逻辑,确保没有遗漏数据。此外,事务超时设置异步导出可能帮助处理长时间运行的任务。最后,异常处理断点续传也是需要考虑的。 还需要验证每个步骤的有效性。例如,分页查询是否使用了正确的起始页数,是否在循环中正确处理了所有数据。流式API是否能有效减少内存使用。同时,检查是否有未关闭的流导致数据未写入。还要考虑服务器性能,比如调整JVM参数,但这可能只是缓解而非根本解决。 最后,确保回答涵盖所有可能的方面,结构清晰,引用相关的参考资料,并生成相关问题供用户进一步探索。需要避免技术术语过多,但保持专业性,确保用户能逐步理解实施解决方案。</think>### Java导出数据不完整的解决方案 在Java中导出大数据时,数据不完整通常由内存溢出、分页逻辑错误、资源未释放或网络中断导致。以下是具体解决步骤: --- #### 1. **分批次处理数据** 通过分页查询避免一次性加载全部数据到内存。 - **SQL优化**:使用`LIMIT offset, size`或`WHERE id > last_id`方式分页,减少数据库压力[^3]。 示例SQL: ```sql SELECT * FROM table WHERE id > #{lastId} ORDER BY id LIMIT 1000 ``` - **分页循环处理**:逐批次读取数据并写入Excel。 ```java int pageSize = 1000; long lastId = 0; while (true) { List<Data> dataList = queryData(lastId, pageSize); if (dataList.isEmpty()) break; writeToExcel(dataList); lastId = dataList.get(dataList.size() - 1).getId(); } ``` --- #### 2. **使用流式Excel写入** Apache POI的`SXSSFWorkbook`支持流式写入,通过设置**内存窗口大小**控制内存占用[^2]。 ```java try (SXSSFWorkbook workbook = new SXSSFWorkbook(100)) { // 每100行刷新到磁盘 Sheet sheet = workbook.createSheet("Data"); for (Data data : dataList) { Row row = sheet.createRow(rowNum++); row.createCell(0).setCellValue(data.getId()); // 其他列... } workbook.write(outputStream); workbook.dispose(); // 清理临时文件 } ``` --- #### 3. **确保资源正确释放** - **显式关闭资源**:在`finally`块中关闭`OutputStream``Workbook`,避免数据未完全写入[^3]。 ```java try { // 写入数据 } catch (IOException e) { // 处理异常 } finally { if (outputStream != null) outputStream.close(); if (workbook != null) workbook.close(); } ``` --- #### 4. **处理网络中断与断点续传** - **分片导出**:将大数据拆分为多个小文件,降低单次导出失败的影响[^2]。 - **记录导出进度**:使用数据库或缓存记录已导出的数据位置,中断后可从断点继续。 --- #### 5. **事务与超时优化** - **设置事务超时**:避免长事务占用数据库连接。 ```java @Transactional(timeout = 60) // 单位:秒 ``` - **异步导出**:通过消息队列或后台线程执行导出任务,防止前端请求超时[^3]。 --- #### 6. **验证数据一致性** - **对比数据库与导出行数**:导出完成后,校验导出的总行数是否与数据库一致。 - **日志监控**:记录每批次处理的起始ID行数,便于排查遗漏。 --- #### 7. **服务器性能调优** - **调整JVM参数**:增大堆内存(如`-Xmx4g`)缓解OOM问题[^2]。 - **限制并发导出**:通过分布式锁或队列控制同时导出的请求数量,防止服务器过载。 --- ### 关键代码示例(使用SXSSFWorkbook) ```java public void exportData(HttpServletResponse response) { try (OutputStream os = response.getOutputStream(); SXSSFWorkbook workbook = new SXSSFWorkbook(100)) { Sheet sheet = workbook.createSheet("Data"); int rowNum = 0; long lastId = 0; while (true) { List<Data> batch = dataService.getBatch(lastId, 1000); if (batch.isEmpty()) break; for (Data data : batch) { Row row = sheet.createRow(rowNum++); row.createCell(0).setCellValue(data.getId()); // 填充其他列... } lastId = batch.get(batch.size() - 1).getId(); } workbook.write(os); } catch (IOException e) { // 记录异常并返回错误信息 } } ``` --- ### 相关问题 1. 如何优化Java导出百万级数据时的内存占用? 2. 分页查询在数据导出中有哪些常见问题? 3. 如何实现Excel导出任务的断点续传功能? 4. 使用SXSSFWorkbook时如何避免临时文件堆积? [^1]: 导出类设计参考 : 分文件导出解决内存溢出 : 分页与流式处理优化 [^4]: 依赖配置与工具选择
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值