有人知道Java的(最好是开源的)PDF布局引擎,能够呈现具有水平分页符的表吗?"水平分页"至少是在BIRT中如何命名该功能,但澄清一下:如果一个表有太多的列以适应可用的页面宽度,我希望该表在多个页面上水平分割,例如10列表,第1-4页输出第1-4页,第2页输出第5-10列.如果表格中有太多行不能垂直放在一页上,那么当然也应该在下面的页面上重复这一点.
到目前为止,搜索产品一直很困难.我认为这样的功能在其他产品中可能会有不同的名称,因此很难使用谷歌阿姨找到合适的解决方案.
到目前为止,我已经尝试过:
BIRT声称支持这一点,但实际的实施是如此错误,它不能使用.我虽然对于这样的功能是不言而喻的,但是行高在所有页面上保持一致,使得在将页面彼此相邻放置时可以对齐行.但是,BIRT会为每个页面分别计算所需的行高.
贾斯帕没有支持.
我也考虑过Apache FOP,但我在XSL-FO规范中找不到任何合适的语法.
对于这项任务,iText通常有点过于"低级别"(使得难以布局预期的PDF文档的其他部分),但似乎不提供支持.
由于似乎有一些其他的报告或布局引擎,可能适合或可能不合适,我发现有点难以猜测究竟要寻找什么,我希望有人可能已经有类似的要求并且至少可以提供一个正确方向的建议.将产品轻松集成到Java服务器应用程序中相对重要,本机Java库是理想的选择.

现在,为了使行在所有页面上保持对齐,行高必须按如下方式计算:
Row1.height = max(A1.height, B1.height, C1.height, D1.height)
Row2.height = max(A2.height, B2.height, C2.height, D2.height)
Run Code Online (Sandbox Code Playgroud)
虽然BIRT目前似乎做了类似的事情:
Page1.Row1.height = max(A1.height, B1.height)
Page2.Row1.height = max(C1.height, D1.height)
Page1.Row2.height = max(A2.height, B2.height)
Page2.Row2.height = max(C2.height, D2.height)
Run Code Online (Sandbox Code Playgroud)

我试图量化和抖动RGB图像有一个奇怪的问题.理想情况下,我应该能够在Java中实现合适的算法或使用Java库,但是对其他语言的实现的引用也可能有用.
以下是输入:
image:24位RGB位图palette:使用RGB值定义的颜色列表max_cols:输出图像中使用的最大颜色数可能重要的是,调色板的大小以及允许的最大颜色数量不一定是2的幂,并且可以大于255.
因此,目标是从所提供的颜色中image选择最多max_cols颜色,palette并仅使用拾取的颜色输出图像,并使用某种误差扩散抖动进行渲染.使用哪种抖动算法并不重要,但它应该是误差扩散变体(例如Floyd-Steinberg)而不是简单的半色调或有序抖动.
性能不是特别重要,预期数据输入的大小相对较小.图像很少会大于500x500像素,提供的调色板可能包含3-400种颜色,颜色数量通常限制在100以下.还可以安全地假设调色板包含多种颜色,覆盖色调,饱和度和亮度的变化.
scolorq使用的调色板选择和抖动将是理想的,但是使用该算法从已定义的调色板而不是任意颜色中选择颜色似乎并不容易.
更确切地说,我遇到的问题是从提供的调色板中选择合适的颜色.假设我例如使用scolorq创建具有N种颜色的调色板,然后将scolorq定义的颜色替换为所提供调色板中最接近的颜色,然后将这些颜色与误差扩散抖动结合使用.这将产生至少类似于输入图像的结果,但是由于所选颜色的不可预测的色调,输出图像可能获得强烈的,不期望的偏色.例如,当使用灰度输入图像和仅具有少量中性灰色调的调色板,但是大范围的棕色调(或更一般地,许多颜色具有相同的色调,低饱和度和亮度变化很大)时,我的颜色选择算法似乎更喜欢这些颜色高于中性灰色,因为棕色色调至少在数学上比灰色更接近所需的颜色.即使我将RGB值转换为HSB并在尝试查找最近的可用颜色时对H,S和B通道使用不同的权重,同样的问题仍然存在.
任何建议如何正确实现,甚至更好的库我可以用来执行任务?
自从Xabster问到,我也可以用这个练习来解释目标,尽管它与如何解决实际问题无关.输出图像的目标是刺绣或挂毯图案.在最简单的情况下,输出图像中的每个像素对应于在某种载体织物上制作的针脚.调色板对应于可用的纱线,通常有几百种颜色.然而,出于实际原因,必须限制实际工作中使用的颜色数量.谷歌搜索gobelin刺绣将举几个例子.
并澄清问题的确切位置......解决方案确实可以分为两个单独的步骤:
这里,第一步是实际问题.如果调色板选择正常,我可以简单地使用所选择的颜色,例如Floyd-Steinberg抖动以产生合理的结果(这实现起来相当简单).
如果我正确理解了scolorq的实现,scolorq结合了这两个步骤,使用调色板选择中的抖动算法知识来创建更好的结果.这当然是一个首选的解决方案,但scolorq中使用的算法稍微超出了我的数学知识.
我上周看了一下WebSockets,并对如何使用Java Servlet API实现服务器端做了一些想法.我没有花太多时间,但在使用Tomcat进行的一些测试中遇到了以下问题,如果不修补容器或至少对HttpServletResponse实现进行容器特定修改,这似乎无法解决:
WebSocket规范要求在101 HTTP响应中定义消息.不推荐使用HttpServletResponse.setStatus(int code,String message)而不提及可用的替换.更改默认的Tomcat配置后,我让Tomcat尊重我的消息字符串,但由于该方法已被弃用,我不确定这是否适用于其他servlet容器.
WebSocket规范要求对响应连接升级请求的HTTP响应中的前几个标头的指定顺序.servlet API不提供指定响应头的顺序的方法,Tomcat将自己的头添加到响应中,将其中的一些放在任何头之前,这些头由servlet实现添加.
由于在提交头时未知响应的内容长度,因此Tomcat会自动切换到响应的分块传输编码,这与WebSocket规范不兼容.
我是否遗漏了一些明显的东西,或者是否真的无法将WebSocket服务器端点集成到基于servlet的Web应用程序中?
基于围绕这个问题的答案的讨论,我发现了Java Hotspot优化器的一个非常奇怪的行为.观察到的行为至少可以在Oracle VM 1.7.0_17中看到,但似乎也出现在较旧的Java 6版本中.
首先,我已经意识到优化器显然意识到标准API中的某些方法是不变的并且没有副作用.执行类似循环时double x=0.5; for(double d = 0; d < Math.sin(x); d += 0.001);,Math.sin(x)不会为每次迭代计算表达式,但优化程序会意识到该方法Math.sin没有相关的副作用,并且结果是不变的,只要x在循环中没有修改.
现在我注意到,只需x从0.5 更改为1.0就禁用了此优化.进一步的测试表明,只有当abs(x)<asin(1/sqrt(2))时才能启用优化.有没有充分的理由,我没有看到,或者是对优化条件的不必要的限制?
编辑:优化似乎在hotspot/src/share/vm/opto/subnode.cpp中实现
我在 Elastic Search 查询中发现了这个问题,但由于ES 日期格式文档链接到java.time.format.DateTimeFormatter类的API 文档,因此该问题并不是真正特定于 ES 的。
简短摘要:我们遇到了超过 9999 年的日期问题,更准确地说,是超过 4 位数字的年份。
存储在 ES 中的文档有一个日期字段,它在索引描述符中定义为格式“date”,使用 DateTimeFormatter 的模式语言对应于“yyyy-MM-dd”。我们正在获取用户输入,使用 org.apache.commons.validator.DateValidator.isValid 也使用模式“yyyy-MM-dd”验证输入,如果有效,我们会使用用户输入创建一个 ES 查询。如果用户输入诸如 20202-12-03 之类的内容,这将失败并执行 execption。搜索词可能不是故意的,但预期的行为是找不到任何东西,而不是软件咳出异常。
问题是 org.apache.commons.validator.DateValidator 在内部使用旧的 SimpleDateFormat 类来验证输入是否符合模式,并且 SimpleDateFormat 解释的“yyyy”的含义类似于:使用至少 4 位数字,但如果需要,允许更多的数字。因此,使用模式“yyyy-MM-dd”创建 SimpleDateFormat 将解析像“20202-07-14”这样的输入,并类似地格式化年超过 9999 的 Date 对象。
新的 DateTimeFormatter 类更加严格,意味着“yyyy”正好是四位数字。它将无法解析像“20202-07-14”这样的输入字符串,也无法格式化年份超过 9999 的 Temporal 对象。值得注意的是,DateTimeFormatter 本身能够处理可变长度字段。例如,常量 DateTimeFormatter.ISO_LOCAL_DATE 不等同于“yyyy-MM-dd”,但符合 ISO8601,允许超过四位数的年份,但将使用至少四位数。此常量是使用 DateTimeFormatterBuilder 以编程方式创建的,而不是使用模式字符串。
ES 不能配置为使用 DateTimeFormatter 中定义的常量,如 ISO_LOCAL_DATE,但只能使用模式字符串。ES 还知道一个预定义模式列表,文档中偶尔也会引用 ISO 标准,但他们似乎误会并忽略了有效的 ISO 日期字符串可以包含五位数年份。
我可以使用多个允许的日期模式列表配置 ES,例如“yyyy-MM-dd||yyyyy-MM-dd”。这将允许在年份中使用四位数和五位数,但对于六位数年份则失败。我可以通过添加另一个允许的模式来支持六位数的年份:“yyyy-MM-dd||yyyyy-MM-dd||yyyyyy-MM-dd”,但是它在七位数年份失败等等。
我是在监督某些事情,还是真的不可能将 ES(或使用模式字符串的 DateTimeFormatter 实例)配置为具有 ISO 标准所使用的至少四位数(但可能更多)的年份字段?
我有以下JAX-RS服务端点的示意图实现:
@GET
@Path("...")
@Transactional
public Response download() {
java.sql.Blob blob = findBlob(...);
return Response.ok(blob.getBinaryStream()).build();
}
Run Code Online (Sandbox Code Playgroud)
调用JAX-RS端点将从数据库中获取Blob(通过JPA)并将结果传回HTTP客户端.使用Blob和流而不是例如JPA的初始BLOB到byte []映射的目的是防止所有数据必须保存在内存中,而是直接从数据库流式传输到HTTP响应.
这按预期工作,我实际上不明白为什么.我是否从与底层JDBC连接和事务关联的数据库中获取Blob句柄?如果是这样,我会期望在从download()方法返回时提交Spring事务,这使得JAX-RS实现以后无法从Blob访问数据以将其流回HTTP响应.
我想知道Sprin MVC控制器方法返回字节数组byte[]表示下载的文件时还是将InputStream对象复制到ServletOutputStream对象时是否存在真正的区别?
我要问的原因是我必须确保下载大文件时不会出现OutOfMemory错误。将通过ServletOutputStream帮助的传递文件避免了吗?
传递字节数组:
byte[] download() {
return getUrlContentAsByteArray();
}
Run Code Online (Sandbox Code Playgroud)
传递ServletOutputStream:
void download(HttpServletResponse response) {
InputStream content = getUrlContentAsStream();
ServletOutputStream outputStream = response.getOutputStream();
response.reset();response.setContentType(ContentType.APPLICATION_OCTET_STREAM.getMimeType());
IOUtils.copyLarge(inputStream, outputStream);
}
Run Code Online (Sandbox Code Playgroud) 首先,根据文档,JAX-WS参考实现应该与Java 5一起使用.
但是,使用最新版本(2.2.7)的二进制包使用Java 6(类版本50.0)进行编译,因此将其与Java 5一起使用将导致抛出UnsupportedClassVersionError.我已经下载了Java源代码并尝试使用Java 5编译它们,但由于依赖库是为Java 6编译的,因此它也无法直接工作.我已经尝试使用"-target 1.5"编译Java 6的新版本,以至少在编译的文件中获得正确的类版本,但我不确定是否遇到其他问题,如果实际在某些时候执行期望Java 6或更新版本.
有没有人知道最新的JAX-WS RI版本,已知可以与Java 5一起使用而没有类似的解决方法?
编辑:
为了回答我的问题的至少一部分,JAX-WS RI实现利用Java 6 SE API中的新功能,并且不会在Java 5上运行,即使这些类是针对目标1.5编译的.至少类org.jvnet.ws.message.BasePropertySet使用类java.util.AbstractMap $ SimpleImmutableEntry,它仅在Java 1.6之后可用.
我必须承认我正在使用Angular2做我的第一步,我在这里遇到了一个问题,我有一些问题需要理解.我使用的是angular2@2.0.0-beta.0,它依赖于rxjs@5.0.0-beta.0.
我的目的是发出HTTP请求(到REST服务)并允许将响应发送给返回的observable的多个订阅者.如果我正确理解文档,我可以使用publish()函数将例如http.post函数返回的Observable转换为ConnectableObservable,通过多次调用ConnectableObservable.subcribe(...)来注册多个subsriber,然后调用ConnectableObservable .connect()实际执行HTTP请求,例如:
var obs: Observable<Response> = this.http.post(...);
var cobs: ConnectableObservable<Response> = obs.publish();
cobs.subscribe(sub1);
cobs.subscribe(sub2);
cobs.connect();
Run Code Online (Sandbox Code Playgroud)
至少我的IDE接缝同意这一点,并没有显示任何警告.运行代码,但我得到以下错误:
EXCEPTION:评估"click"时出错
ORIGINAL EXCEPTION:TypeError:obs.publish不是函数
如果我obs在调试器中检查对象,则实际上只有一小部分记录的函数可用.如果我查看Observable类的实现,确实只实现了一些记录的函数.大多数函数(其中包括publish函数)仅在没有任何实际实现的情况下声明为函数签名.
我在这里做了一些明显错误的事情,还是我完全误解了如何使用RxJS observables?
如果重要的话,我正在构建gulp,使用npm来解析和下载依赖项,并在我的node_modules目录中包含rxjs/bundles/Rx.js.
java ×7
angular ×1
blob ×1
download ×1
java-5 ×1
jax-rs ×1
jax-ws ×1
jvm-hotspot ×1
observable ×1
optimization ×1
rxjs ×1
servlets ×1
spring-mvc ×1
websocket ×1