import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import com.sbdcpn.upload.FtpClient;
import com.sbdcpn.utils.Log;
import com.sbdcpn.xmlparse.pagecfg.PageCfgXMLUtil;
public class BigDataWriteXmlBo {
private final int records = 1000;
/**
* 将数据保存到xml上
* @throws ParserConfigurationException
* @throws IOException
* @throws TransformerException
* @throws SAXException
* @throws InterruptedException
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void generateXML() throws IOException, TransformerException, SAXException, InterruptedException{
SAXTransformerFactory fac = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
TransformerHandler handler = fac.newTransformerHandler();
Transformer transformer = handler.getTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");//
// 设置输出采用的编码方式
transformer.setOutputProperty(OutputKeys.INDENT, "yes");// 是否自动添加额外的空白
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");// 是否忽略xml声明
//文件名 :前七位SWPM001为电文号+14位日期(年月日时分秒)
StringBuffer fileName = new StringBuffer("SWPM001_");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
fileName.append(sdf.format(new Date())).append(".xml");
FileOutputStream fos = new FileOutputStream(fileName.toString());
Result resultxml = new StreamResult(fos);
handler.setResult(resultxml);
//Message标签的属性
AttributesImpl msgAtt = new AttributesImpl();
msgAtt.addAttribute("", "", "MsgID", "", "SWPM001");
msgAtt.addAttribute("", "", "ResourceID", "", "SW");
handler.startDocument();
handler.startElement("", "", "Message", msgAtt);
//空属性
AttributesImpl fieldAtt = new AttributesImpl();
//取得总记录数,进行分页处理
long count = queryAllRows();
long page = count / records;
if (count % records != 0) {
page = page + 1;
}
String four = "\n ";
String eight = "\n ";
//开始行号,结束行号
long start = 1, end = records;
//根据页数进行循环
for (long j = 1; j <= page; j++) {
// 分页取得目录数据
List<Map> data = this.queryStockInventory(start, end);
//按行循环一页中的数据
for (int i = 0; i < data.size(); i++) {
handler.characters(four.toCharArray(), 0, four.length());//行缩进
Map<String, String> rec = data.get(i);
//行结点属性
AttributesImpl dataRowAtt = new AttributesImpl();
dataRowAtt.addAttribute("", "", "id", "", String.valueOf(start - 1 + i));
// 行结点
handler.startElement("", "", "DataRow", dataRowAtt);
rec.remove("row_num");
Iterator it = rec.entrySet().iterator();
//按列循环生成数据结点
while (it.hasNext()) {
handler.characters(eight.toCharArray(), 0, eight.length());// 列缩进
Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
String key = entry.getKey();
String value = entry.getValue();
// 用字段名作为标签名,对应的数据作为内容
handler.startElement("", "", key, fieldAtt);
handler.characters(value.toCharArray(), 0, value.length());
handler.endElement("", "", key);
}
handler.characters(four.toCharArray(), 0, four.length());//行缩进
handler.endElement("", "", "DataRow");
}
start = end + 1;
end = end + records;
handler.endDocument();// 文档结束,同步到磁盘
handler.startDocument();
}
handler.endElement("", "", "Message");
handler.endDocument();
fos.close();//不关闭的话,后面删除不了文件
uploadFile(fileName.toString());// 上传文件至ftp
}
/**
* 把生成出来的文件,上传到ftp;上传失败后,1分钟后再次尝试上传,连续三次不成功便停止
* @param fileName 文件名
* @param filePath 路径
* @throws InterruptedException
*/
private void uploadFile(String fileName) throws InterruptedException {
String[] path = PageCfgXMLUtil.getInstance().getPageConstByKey("stockFtpXmlPath").split(" ");
int reSend = 1;
//上传失败时,1分钟后再次尝试
while (reSend <= 3) {
FtpClient ftp = new FtpClient();
ftp.Connect(path[0], Integer.parseInt(path[1]));// ip与端口
ftp.Login(path[3], path[4]);// 用户名与密码
ftp.SetCurDir(path[2]);// 目录
boolean isUpload = ftp.PutFile(fileName, fileName);
ftp.DisConnect();
if (isUpload) {
_log.showLog(fileName + "成功上传到FTP服务器上!");
break;
} else {
_log.showLog(fileName + "尝试" + reSend + "次后,上传到FTP服务器失败!");
reSend++;
Thread.sleep(60000);
}
}
File file = new File(fileName);
String flag = file.delete() ? "成功!" : "失败!";
_log.showLog("删除临时文件:" + fileName + flag);
}
/**
* 分页查询,示例查询,假设数据有十万条
* @return
*/
@SuppressWarnings("rawtypes")
private List queryStockInventory(long start, long end) {
StringBuffer insertInto = new StringBuffer();
insertInto.append(" SELECT")
.append(" tmp_stock_inv.*")
.append(" FROM(")
.append(" SELECT *,")
.append("rownum row_num")
.append(" FROM table")
.append(" WHERE rownum <=").append(end)
.append(") tmp_stock_inv")
.append(" WHERE")
.append(" tmp_stock_inv.row_num >=").append(start);
_log.showLog("查询:" + insertInto.toString());
return _dao.query(insertInto.toString());
}
/**
* 取得总记录数
* @return
*/
@SuppressWarnings("unchecked")
private int queryAllRows() {
StringBuffer insertInto = new StringBuffer();
insertInto.append("SELECT count(*) rows_count FROM stock_inventory WHERE stock_qty > 0");
_log.showLog("查询总记录数:" + insertInto.toString());
Map<String,String> rs = (Map<String,String>)_dao.queryOneRow(insertInto.toString());
return Integer.parseInt(rs.get("rows_count"));
}
}