解决The entity "" was referenced, but not declared的方案

解决 The entity "" was referenced, but not declared的方案

需求:生成的PDF通知书中药展示下面如图所示的区间形式


需求分析:
由于页面录入的形式采用如下图所示方式

那么认购金额对应 InvestAmountMin字段,对应的年化收益率对应InvestProfit字段,因此存储的数据库结构如下;
listing_trade_invest存储年化收益率列表的数据表结构
InvestAmountMin字段表示投资金额中的起投金额
InvestProfit字段表示投资金额区间内的年化收益率

怎么怎么在PDF中展示呢

解决方案:
第一步:从数据库查询出来每个项目对应的年化收益率列表‘’
第二步:根据每条数据的起投金额进行自然排序
第三步:循环年化收益率列表,重新创建一个带有每一条记录中的年化收益率的投资上限的新的对象,将原有的属性拷贝到新建的对象中,而对于每一个新的对象的投资上限属性做特殊处理,如果处理的是年化收益率列表中的最后一个经过拷贝的新对象,那么它对应的投资上限是项目的投资上限,除此之外凡是小于列表个数的新的对象的投资上限都是下一挑拨记录的起投金额,新的对象组装完成后重新添加到一个新的对象列表中
第四步:将上述新组装的年化收益列表传回页面进行显示
处理的代码:
       /**
	 * 处理起投金额和对应年化收益率显示问题
	 *
	 * @param project
	 * @return
	 * @throws Exception 
	 * @author hongwei.lian
	 * @date 2018年6月21日 下午2:12:24
	 */
	private List<ListingTradeInvest> handleListingTradeInvest(ProjectBaseinfo project) throws Exception {
		List<ListingTradeInvestVo> tradeInvestVoList = projectBaseinfoService.findProjectTradeInvestList(project.getId());
		//-- 自然排序(从小到大)
		tradeInvestVoList.sort(
				(tradeInvest1, tradeInvest2) 
				-> 
				tradeInvest1.getInvestAmountMin().compareTo(tradeInvest2.getInvestAmountMin()));
		//-- 重新组装数据以区间形式显示投资金额
		List<ListingTradeInvest> tradeInvestList = new ArrayList<>(tradeInvestVoList.size());
		for (int i = 0; i < tradeInvestVoList.size(); i++) {
			ListingTradeInvest tradeInvest = new ListingTradeInvest();
			BeanUtils.copyProperties(tradeInvest, tradeInvestVoList.get(i));
			BigDecimal investAmountMax = BigDecimal.ZERO;
			if (i < tradeInvestVoList.size()-1) {
				investAmountMax = tradeInvestVoList.get(i+1).getInvestAmountMin();
			} else if (i == tradeInvestVoList.size()-1) {
				//-- 如果是最后一项,设置为项目投资上限
				investAmountMax = project.getInvestAmountMax();
			}
			tradeInvest.setInvestAmountMax(investAmountMax);
			tradeInvestList.add(tradeInvest);
		}
		return tradeInvestList;
	}

由于通知书上传的方式使用的Velocity模板方式生成,因此HTML模板也需要做适当的处理

循环后端传过来的年化收益率列表,那么需要注意的一个问题是小于等于号和小于号的在Velocity模板上的使用问题,花了我一个小时的时间去搞定。。。
如果使用下面的转义字符

那么在使用Velocity生成HTML之后,再使用IText将HTML转换为PDF格式中间解析会抛出如下异常
[2018-06-25 17:14:53,973] [ERROR] [@@ (ptoms)  (com.huajin.ptoms.controller.project.debt.ProjectListingFilingLetterController)  (printLetter)  (-)  (-)  (-)  (org.xhtmlrenderer.util.XRRuntimeException:Can't load the XML resource (using DOM parser). The entity "le" was referenced, but not declared.) @@] [?] [] - [http-bio-127.0.0.1-8004-exec-1]
org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using DOM parser). The entity "le" was referenced, but not declared.
	at org.xhtmlrenderer.resource.XMLResource$XMLResourceBuilder.createXMLResource(XMLResource.java:198) ~[flying-saucer-core-9.1.1.jar:?]
	at org.xhtmlrenderer.resource.XMLResource.load(XMLResource.java:75) ~[flying-saucer-core-9.1.1.jar:?]
	at org.xhtmlrenderer.pdf.ITextRenderer.setDocumentFromString(ITextRenderer.java:161) ~[flying-saucer-pdf-itext5-9.1.1.jar:?]
	at com.huajin.exchange.utils.PdfUtils.htmlToPdf(PdfUtils.java:37) ~[fae-exchange-common-1.0.0.jar:?]
	at com.huajin.ptoms.service.ProjectFilingLetterSerivce.createListingNoticeFile(ProjectFilingLetterSerivce.java:235) ~[classes/:?]
	at com.huajin.ptoms.service.ProjectFilingLetterSerivce.downListingLetter(ProjectFilingLetterSerivce.java:151) ~[classes/:?]
	at com.huajin.ptoms.controller.project.debt.ProjectListingFilingLetterController.printLetter(ProjectListingFilingLetterController.java:106) ~[classes/:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:624) ~[servlet-api.jar:?]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) ~[servlet-api.jar:?]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat7-websocket.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:108) ~[spring-boot-actuator-1.5.2.RELEASE.jar:1.5.2.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.cloud.sleuth.instrument.web.TraceFilter.doFilter(TraceFilter.java:145) ~[spring-cloud-sleuth-core-1.2.0.RELEASE.jar:1.2.0.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) ~[spring-boot-actuator-1.5.2.RELEASE.jar:1.5.2.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
	at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
	at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
	at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) ~[catalina.jar:7.0.70]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) ~[catalina.jar:7.0.70]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) ~[catalina.jar:7.0.70]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) ~[catalina.jar:7.0.70]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442) ~[catalina.jar:7.0.70]
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082) ~[tomcat-coyote.jar:7.0.70]
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623) ~[tomcat-coyote.jar:7.0.70]
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) ~[tomcat-coyote.jar:7.0.70]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_121]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_121]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-coyote.jar:7.0.70]
	at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121]
Caused by: org.xml.sax.SAXParseException: The entity "le" was referenced, but not declared.
	at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257) ~[?:1.8.0_121]
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339) ~[?:1.8.0_121]
	at org.xhtmlrenderer.resource.XMLResource$XMLResourceBuilder.createXMLResource(XMLResource.java:195) ~[flying-saucer-core-9.1.1.jar:?]
	... 80 more
分析最后的报错原因是DOM在解析XML时使用了未定义的符号,于是接着看了HTML转换为PDF的方法,继续分析报错的原因 是由于未定义HTML的DOCTYPE,致使SAX将内容按照xml默认定义进行解析,而xml中&开头表示可解析的实体,这个实体被DTD预先定义。

方案一:
加入正确的DOCTYPE,如:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
因为自己的HTML模板使用的是HTML5定义的头<!DOCTYPE html>,并没有XHTML定义的东西,也就是在解析XML的时候报错。

使用实体字符


方案二:
使用<!DOCTYPE html>,使用

使用实体符号
小于等于号:&#8804;
小于号:&#60;


最终PDF结果

猜你喜欢

转载自blog.csdn.net/erlian1992/article/details/80806814