Java 如何移动整个布局以适应不同打印机上的预打印表单

Java 如何移动整个布局以适应不同打印机上的预打印表单,java,jasper-reports,Java,Jasper Reports,我们有使用Java、Hibernate、Spring和Jasper Report 5.6开发的美国医疗保健账单产品。正在使用CMS 1500和UB04表单打印 我们希望打印预打印表单中的值,即用户将此预打印表单保存在打印机中,并从应用程序中打印框中的值 因此,我们在Jasper报告中附加了图像,并将文本框放在每个框中。打印正确,但如果用户更换打印机,则对齐将成为一个问题。作为另一个脏选项,我们获取副本并对齐该打印机,因此现在对于每台打印机,我们都有单独的jasper报告文件,即使打印的值相同 我

我们有使用Java、Hibernate、Spring和Jasper Report 5.6开发的美国医疗保健账单产品。正在使用CMS 1500和UB04表单打印

我们希望打印预打印表单中的值,即用户将此预打印表单保存在打印机中,并从应用程序中打印框中的值

因此,我们在Jasper报告中附加了图像,并将文本框放在每个框中。打印正确,但如果用户更换打印机,则对齐将成为一个问题。作为另一个脏选项,我们获取副本并对齐该打印机,因此现在对于每台打印机,我们都有单独的jasper报告文件,即使打印的值相同

我的客户要求给他们一个选项,以单独的形式设置X和Y值,然后使用这些值正确打印

所以问题是我们能在jasper报告中做到这一点吗


移动所有报告元素的最简单方法是修改报告页边距

jrxml
加载到
JasperDesign
对象中,并根据需要切换边距。可以在x中移动的最小值是原始报告边距,最大值取决于您的报告(当然,columWidth不能变为0,但没有真正意义检查此值以更好地定义最大值)

示例:

JasperDesign design = JRXmlLoader.load("YourReport.jrxml");
moveDesign(design,x,y);
JasperReport report = JasperCompileManager.compileReport(design);

private void moveDesign(JasperDesign design, int x, int y) {
    int maxX = 100; //I define it so that elements is not out of report
    int maxY = 100;

    int pageWidth = design.getPageWidth();
    int intitalLeftMargin = design.getLeftMargin();
    int intitalRightMargin = design.getRightMargin();
    int intitalTopMargin= design.getTopMargin();

    //Check that not less then 0 and not more then my max       
    int newLeftMargin = Math.min(Math.max(intitalLeftMargin+x,0),maxX);
    int newTopMargin = Math.min(Math.max(intitalTopMargin+y,0),maxY);

    //set our new margins
    int newColumWidth = pageWidth - newLeftMargin - intitalRightMargin;
    design.setLeftMargin(newLeftMargin);
    design.setTopMargin(newTopMargin);
    design.setColumnWidth(newColumWidth);
}
缺点是你需要重新编译你的报告(这需要几毫秒)

如果执行速度至关重要,另一个解决方案(更复杂但可能更快)是移动
JasperPrint

我将把完整的代码留给OP,但它与此类似

List<JRPrintPage> pages = jasperPrint.getPages();
for (JRPrintPage jrPrintPage : pages) {
    List<JRPrintElement> elements = jrPrintPage.getElements();
    for (JRPrintElement jjpe : elements) {
        jjpe.setX(newX);
        jjpe.setY(newX);    
    }   
}
List pages=jasperPrint.getPages();
用于(JRPrintPage JRPrintPage:pages){
List elements=jrPrintPage.getElements();
for(JRPrintElement jjpe:elements){
jjpe.setX(newX);
杰杰普·塞蒂(纽约);
}   
}

为了更好地理解,如果我声明您正在寻找移动所有具有用户提供的X和Y值的JR元素,我是否正确理解了该问题?。。。。。您正在寻找java或jrxml的解决方案吗?此外,X和Y值可以是负值还是仅为正值?是的,您的理解是正确的。我正在寻找java的解决方案。X和Y可以是消极的,也可以是积极的。我编辑你的帖子,反映你的需要,这样对别人可能更有用。是的,我急于找到解决办法。现在一切都好了。你的解决方案非常适合我。用最快的方法,我们不需要重新编译?JasperDesign=null;design=jrxmloader.load(reportPath);JR元素jasperement=null;jasperement=design.getPageHeader().getElementByKey('keyname');如果(jaspereElement!=null){jaspereElement.setX(tmp.getXpos());}这里我没有设置jaspereElement.setY,因为JRElement中没有方法。我们如何设置真实位置?最快的方法,不,您不需要重新编译,jrxml到.jasper,但在您的情况下,用户打印几乎看不到任何差异(0.1-0.2秒),主要是我添加了最快的方法,如果有人需要执行此批处理(生成1000个报告),您需要将其转换到正确的类(它是textElement还是image??),如果您不知道使用的是JRBaseElement((JRBaseElement)tmp)。setY(…)…是的。Petter小更正。从您的示例中,我们需要保存JXML文件,然后按照以下方式编译JasperCompileManager.WriterReportToXmlFile(设计,报告路径);JasperCompileManager.compileReportToFile(设计,输出文件);