我写了个组件用来从XML文件中读取其中某些节点的值,然后用数据库中的相应的数据来替换其中部分节点值,用更改后的文件创建一个新的XML文件,在不通过Tomcat和Sevlet的时候能正常工作,但在Tomcat中通过Servlet来调用这个组件时就报这个错误:
The output format must have a '{http://xml.apache.org/xalan}content-handler' property!传入的参数都是新文件名(带地址,如:D:\result.xml)
请各路高手帮忙解决,非常感谢!
The output format must have a '{http://xml.apache.org/xalan}content-handler' property!传入的参数都是新文件名(带地址,如:D:\result.xml)
请各路高手帮忙解决,非常感谢!
import javax.servlet.http.*;
import javax.naming.*;
import java.util.*;
import java.io.*;/**
* <p>File Name : ReportServiceServlet.java </p>
* <p>Description: 报表应用Web控制器类 </p>
* <p>Create Date: 2005-12-12 </p>
* <p>Modify Date: 2005-12-12 </p>
* <p>Company : </p>
* @author ylpeng
* @version 1.0
*/
public class ReportServiceServlet extends HttpServlet
{
/**
* Function:服务方法,截取报表应用中所有Web请求,根据事件类型进行相应转发处理
* @param request HttpServletRequest Web请求对象
* @param response HttpServletResponse Web响应对象
*/
public void service(HttpServletRequest request,HttpServletResponse response){
response.setContentType("text/html");
RequestDispatcher dispatcher = null;
try{
response.setCharacterEncoding("GBK");
request.setCharacterEncoding("GBK");
String event = request.getParameter("event").trim();
//初始化报表列表
if(event.equals("load")){
loadReportList(request,response);
dispatcher = request.getRequestDispatcher("/report/index.jsp");
}
//创建请求的报表
else if(event.equals("build")){
buildReport(request,response);
dispatcher = request.getRequestDispatcher("/report/index.jsp");
}
else
throw new Exception("请求事件错误");
dispatcher.forward(request,response);
}
catch(Exception e){
try{
PrintWriter writer = response.getWriter();
writer.println(e.getMessage());
}
catch(IOException ioe){
ioe.printStackTrace();
}
}
}
/**
* Function:从数据库中获取当前用户能查看的报表集合并存入page_bean
* @param request HttpServletRequest Web请求对象
* @param response HttpServletResponse Web响应对象
*/
private void loadReportList(HttpServletRequest request,HttpServletResponse response)
throws Exception
{
ReportDAO dao = new ReportDAO();
ReportPageBean pageBean = new ReportPageBean();
String sqlStr = "select report_id,report_name from trm_report";
ArrayList[] reports = dao.getReportList(sqlStr);
pageBean.setReports(reports);
pageBean.setReportCount(((ArrayList)reports[0]).size());
HttpSession session = request.getSession(true);
session.setAttribute("page_bean",pageBean);
}
/**
* Function:根据用户请求的资源创建报表
* @param request HttpServletRequest Web请求对象
* @param response HttpServletResponse Web响应对象
*/
private void buildReport(HttpServletRequest request,HttpServletResponse response)
throws Exception
{
ReportDAO dao = new ReportDAO();
XMLReport report = new XMLReport();
String area = request.getParameter("area").trim();
String startDate = request.getParameter("startDate").trim();
String endDate = request.getParameter("endDate").trim();
String reportID = request.getParameter("reportID").trim();
String template = dao.getTemplateFile(reportID);
template = getServletConfig().getServletContext().getRealPath(template);
String target = template.substring(0,template.lastIndexOf(".")) + "-result.xml";
report.runReport(template,target,area,startDate,endDate);//调用生成报表工具类,出错的就是这句
//设置模型Bean中的报表文件属性
HttpSession session = request.getSession(true);
ReportPageBean pageBean = (ReportPageBean)session.getAttribute("page_bean");
pageBean.setCurrentReport(target);
}
}
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.w3c.dom.*;/**
* <p>File Name : XMLReport.java </p>
* <p>Description: 基于XML的报表应用API,用数据库中的相应值替换报表模板中标准编码值 </p>
* <p>Create Date: 2005-12-08 </p>
* <p>Modify Date: 2005-12-12 </p>
* <p>Company : </p>
* @author ylpeng
* @version 1.0
*/
public class XMLReport
{
private DocumentBuilderFactory factory;
private DocumentBuilder builder;
/**
* Function:构造函数,初始化主要的通用的XML API
*/
public XMLReport(){
try{
factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
builder = factory.newDocumentBuilder();
builder.setErrorHandler(new MyErrorHandler());
}
catch(ParserConfigurationException parserException){
parserException.printStackTrace();
}
}
/**
* Function:得到模板文件中的所有标准编码节点的编码集合,并存入内存变量中
* @return ArrayList
* @param fileName String 模板文件名
*/
public ArrayList getStandardCodeList(String fileName){
ArrayList codeList = new ArrayList();
Document document;
try {
document = builder.parse(new File(fileName.trim()));
Node root = document.getDocumentElement();
if(root.getNodeType() == Node.ELEMENT_NODE){
Element rootElement = (Element)root;
NodeList dataNodeList = rootElement.getElementsByTagName("Data");
for(int i = 0;i < dataNodeList.getLength();i++){
Node code = dataNodeList.item(i);
Text codeValue = (Text)code.getChildNodes().item(0);
String codeText = codeValue.getData().trim();
if(codeText.startsWith("$$",0)){
codeList.add(codeText);
}
}
}
}
catch(IOException ioException){
ioException.printStackTrace();
System.exit(1);
}
catch(SAXException saxException){
saxException.printStackTrace();
}
return codeList;
}
/**
* Function:根据报表模板和指标值在数据库中的映射集合创建报表文件
* @param sourceFile String 模板文件名
* @param targetFile String 最后生成的报表文件名
* @param codeMapping HashMap 模板中的指标集合和对应的指标值的集合构成的Map对象
*/
public void buildNewFile(String sourceFile,String targetFile,HashMap codeMapping){
Document document;
try{
document = builder.parse(new File(sourceFile.trim()));
Node root = document.getDocumentElement();
if(root.getNodeType() == Node.ELEMENT_NODE){
Element rootElement = (Element)root;
NodeList dataNodeList = rootElement.getElementsByTagName("Data");
for(int i = 0;i < dataNodeList.getLength();i++){
Node code = dataNodeList.item(i);
Text codeValue = (Text)code.getChildNodes().item(0);
String codeText = codeValue.getData().trim();
if(codeText.startsWith("$$",0)){
if(codeMapping.containsKey(codeText)){
Text mappingValue = document.createTextNode(
codeMapping.get(codeText).toString());
code.replaceChild(mappingValue,codeValue);
}
else codeValue.setData("");
}
}
}
Source xmlSource = new DOMSource(document);
Result result = new StreamResult(new FileOutputStream(targetFile.trim()));
//StreamResult result = new StreamResult(new File(targetFile.trim()));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT,"yes");
transformer.setOutputProperty(OutputKeys.STANDALONE,"yes");
transformer.transform(xmlSource, result);
}
catch(IOException ioException){
ioException.printStackTrace();
System.exit(1);
}
catch (SAXException saxException){
saxException.printStackTrace();
}
catch(TransformerException transformerError){
System.err.println("Error transforming document");
transformerError.printStackTrace();
}
}
/**
* Function:根据报表所需参数运行报表
* @param sourceFile String 模板文件名
* @param targetFile String 最后生成的报表文件名
* @param areaCode String 本地网编码
* @param startDate String 开始时间
* @param endDate String 结束时间
*/
public void runReport(String sourceFile,String targetFile,String areaCode,String startDate,String endDate){
ArrayList codeList = this.getStandardCodeList(sourceFile);
String sqlString = " select '$$'||trim(area_id)||'-'||trim(measure_item_id),sum(measure_value) " +
" from pd_martdata.bas_measure_value where Time_Cd BETWEEN '" + startDate.trim() + "' AND '" +
endDate.trim() + "' AND '$$'||trim(area_id)||'-'||trim(measure_item_id) in ";
String str = "";
for(int i = 0;i < codeList.size();i++){
str += "'" + codeList.get(i).toString().trim() + "',";
}
str = str.substring(0,str.length() - 1);
str = sqlString + "(" + str + ")";
if(!areaCode.equals("all"))
str += " AND trim(area_id) LIKE '" + areaCode.trim() + "%' ";
str += " group by 1 order by 1;";
//得到标准编码的映射集合
HashMap codeMapping = ReportDAO.getCodeMapping(str);
this.buildNewFile(sourceFile,targetFile,codeMapping);
}
/**
* Function:程序入口,测试用
*/
public static void main(String[] args){
XMLReport report = new XMLReport();
report.runReport("D:\\report.xls","D:\\result.xls","all","20040101","20051231");
}
}