论坛首页 Java企业应用论坛

介绍一个PDF的生成方案

浏览 150991 次
该帖已经被评为良好帖
作者 正文
   发表时间:2009-11-10  
能不能实现ie打开pdf文件 啊?
或者说直接在线打印pdf文件,而不用下载后再打印,或者通过applet来实现?
0 请登录后投票
   发表时间:2009-11-10  
这下写PDF文件确实方便了很多了,谢谢楼主分享。
0 请登录后投票
   发表时间:2009-11-10  
ie是直接打开还是另存为pdf,应该是浏览器端自己设置的吧,我现在的浏览器就是直接打开,我还发愁怎么样让它不打开呢。。
0 请登录后投票
   发表时间:2009-11-10  
yye_javaeye 写道
ie是直接打开还是另存为pdf,应该是浏览器端自己设置的吧,我现在的浏览器就是直接打开,我还发愁怎么样让它不打开呢。。


可以设置output的格式,是附件还是打开。google一下。
0 请登录后投票
   发表时间:2009-11-10  
终于弄好了,图片页眉页脚,分页,用了很多css3的东西,idea不支持,写起来真费劲啊,代码不是很好看,总之功能先完成了,回头再改了。
action:
import java.util.List;
import java.io.*;

import org.apache.struts2.ServletActionContext;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.w3c.dom.Document;
import org.w3c.dom.html.HTMLDocument;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 报告测试
 *
 */
public class ReportSample extends CommonAction {
    private IRole roleService;
    private List<Role> roleList;
    private String ifExp;
    private InputStream expIs;
    private String fileName;

    public String sample1() {
        roleList = roleService.getTeacherScopeRoleList();
        if ("yes".equals(ifExp)) {
            try {
                String ftlDir = ServletActionContext.getServletContext().getRealPath("/ftl/report");
                Configuration cfg = new Configuration();
                cfg.setDefaultEncoding("UTF-8");
                cfg.setDirectoryForTemplateLoading(new File(ftlDir));
                cfg.setObjectWrapper(new DefaultObjectWrapper());

                Template template = cfg.getTemplate("sample1.ftl");
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(baos);
                template.process(this, osw);
                osw.flush();
                osw.close();

                ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
                ITextRenderer renderer = new ITextRenderer();
                renderer.setDocumentFromString(baos.toString());

                ITextFontResolver fontResolver = renderer.getFontResolver();
                fontResolver.addFont("c:/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                renderer.getSharedContext().setUserAgentCallback(new HttpURLUserAgent(renderer.getOutputDevice()));
                renderer.layout();
                renderer.createPDF(pdfOut, true);
                this.expIs = new ByteArrayInputStream(pdfOut.toByteArray());
                baos.close();
                pdfOut.close();
                fileName = "测试中文.pdf";
            } catch (Exception e) {
                logger.error(e);
                throw new CommException("export error", e);
            }
            return "export";
        } else {
            return "sample1";
        }
    }

    public IRole getRoleService() {
        return roleService;
    }

    public void setRoleService(IRole roleService) {
        this.roleService = roleService;
    }

    public List<Role> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<Role> roleList) {
        this.roleList = roleList;
    }

    public String getIfExp() {
        return ifExp;
    }

    public void setIfExp(String ifExp) {
        this.ifExp = ifExp;
    }

    public InputStream getExpIs() {
        return expIs;
    }

    public void setExpIs(InputStream expIs) {
        this.expIs = expIs;
    }

    public String getFileName() {
        try {
            return new String(fileName.getBytes(),"ISO8859-1");
        } catch (UnsupportedEncodingException e) {
            return "test.pdf";
        }
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}

freemarker:
<html>
<head>
    <title>报告测试1</title>
    <style type="text/css">
        <!--
        body {
            font-family: SimSun;
        }

        table {
            -fs-table-paginate: paginate;
        }

        div.header-left {
            display: none
        }

        div.header-right {
            display: none
        }

        div.footer-left {
            display: none
        }

        div.footer-right {
            display: none
        }

        @media print {
            div.header-left {
                display: block;
                position: running(header-left);
            }

            div.header-right {
                display: block;
                position: running(header-right);
            }

            div.footer-left {
                display: block;
                position: running(footer-left);
            }

            div.footer-right {
                display: block;
                position: running(footer-right);
            }
        }

        @page {
            margin: 0.65in;
            border: thin solid black;
            padding: 1em;
            @top-left { content: element(header-left) };
            @top-right { content: element(header-right) };
            @bottom-left { content: element(footer-left) };
            @bottom-right { content: element(footer-right) };
        }

        #pagenumber:before {
            content: counter(page);
        }

        #pagecount:before {
            content: counter(pages);
        }

        -->
    </style>
</head>
<body>
<div id="header-left" class="header-left" align="left"><img src="http://localhost:8081/xxx/images/switch_left.gif" width="10" height="10"/>ttt<hr/>打印日期1:</div>
<div id="header-right" class="header-right" align="right">报告对象:<hr/>产生日期1:</div>

<div id="footer-left" class="footer-left" align="left"><hr/>Copyright 2000</div>
<div id="footer-right" class="footer-right" align="right"><hr/>第 <span id="pagenumber"/> 页</div>
<table border="0" width="100%" height="100%" cellpadding="0" cellspacing="0">
    <tr>
        <td colspan="10" align="center"><img width="500" height="300"
                                             src="http://localhost:8081/xxx/report/barChartSample!sample1.action"/>
        </td>
    </tr>
    <tr>
        <td>id</td>
        <td>名称</td>
        <td>创建时间</td>
        <td>角色类型</td>
        <td>适用范围</td>
    </tr>
    <#assign i=0>
    <#list roleList as role>
    <#assign i = i+1>
    <tr>
        <td>${role.roleId}</td>
        <td>${role.roleName}</td>
        <td>${role.createTime?datetime}</td>
        <td>${role.roleTypeId}</td>
        <td>${role.roleApplyScopeId}</td>
    </tr>
    </#list>
</table>
</body>
</html>

改写的UserAgent:
import org.xhtmlrenderer.pdf.ITextUserAgent;
import org.xhtmlrenderer.pdf.ITextOutputDevice;
import org.xhtmlrenderer.pdf.ITextFSImage;
import org.xhtmlrenderer.resource.ImageResource;
import org.xhtmlrenderer.resource.CSSResource;
import org.xhtmlrenderer.util.XRLog;

import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedHashMap;

import com.lowagie.text.Image;

/**
 * 修改xhtmlrenderer获取css和image资源的方式为网络
 *
 */
@SuppressWarnings("unchecked")
public class HttpURLUserAgent extends ITextUserAgent {
    /**
     * an LRU cache
     */
    private int imageCacheCapacity = 16;
    private LinkedHashMap imageCache =
            new LinkedHashMap(imageCacheCapacity, 0.75f, true) {
                private static final long serialVersionUID = -2333998499957890105L;

                protected boolean removeEldestEntry(java.util.Map.Entry eldest) {
                    return size() > imageCacheCapacity;
                }
            };

    public HttpURLUserAgent(ITextOutputDevice outputDevice) {
        super(outputDevice);
    }

    @Override
    public CSSResource getCSSResource(String uri) {
        InputStream is = null;
        uri = resolveURI(uri);
        try {
            URLConnection uc = new URL(uri).openConnection();
            uc.connect();
            is = uc.getInputStream();
        } catch (MalformedURLException e) {
            XRLog.exception("bad URL given: " + uri, e);
        } catch (IOException e) {
            XRLog.exception("IO problem for " + uri, e);
        }
        return new CSSResource(is);
    }

    @Override
    public ImageResource getImageResource(String uri) {
        ImageResource ir;
        uri = resolveURI(uri);
        ir = (ImageResource) imageCache.get(uri);
        if (ir == null) {
            try {
                ir = new ImageResource(new ITextFSImage(Image.getInstance(new URL(uri))));
            } catch (Exception e) {
                e.printStackTrace();
            }
            imageCache.put(uri, ir);
        }
        if (ir == null) ir = new ImageResource(null);
        return ir;
    }
}

struts2 配置文件:
        <action name="reportSample" class="action.ReportSample">
            <result name="sample1" type="freemarker">/ftl/report/sample1.ftl</result>
            <result name="export" type="stream">
                <param name="inputName">expIs</param>
                <param name="contentType">application/pdf</param>
                <param name="contentDisposition">inline;filename="${fileName}"</param>
            </result>
        </action>

0 请登录后投票
   发表时间:2009-11-10  
yye_javaeye 写道
ie是直接打开还是另存为pdf,应该是浏览器端自己设置的吧,我现在的浏览器就是直接打开,我还发愁怎么样让它不打开呢。。

那你在浏览器里打开pdf 如何实现打印,直接调用浏览器的功能吗?还是调用pdf自己的打印功能实现在线打印?
0 请登录后投票
   发表时间:2009-11-10  
blackbat 写道
yye_javaeye 写道
ie是直接打开还是另存为pdf,应该是浏览器端自己设置的吧,我现在的浏览器就是直接打开,我还发愁怎么样让它不打开呢。。

那你在浏览器里打开pdf 如何实现打印,直接调用浏览器的功能吗?还是调用pdf自己的打印功能实现在线打印?

我发的struts2配置中,inline改为attachment即可让浏览器保存pdf而不是直接打开,另,我在firefox上测试时,直接打开pdf的情况下是显示pdf的打印按钮的,回头在ie上再试试
0 请登录后投票
   发表时间:2009-11-18  
我在转换时,中文的字段到行末都不自动换行都要延长一段看不见,只有英文到本行末尾自动换行,不知道是css的问题,还是flying Scaucer本身就对中文解析的问题?
0 请登录后投票
   发表时间:2009-11-19  
xijieqjx 写道
我在转换时,中文的字段到行末都不自动换行都要延长一段看不见,只有英文到本行末尾自动换行,不知道是css的问题,还是flying Scaucer本身就对中文解析的问题?


经过尝试,这个问题的确是存在的,不过至今我还没找到解决方案。哎~~~,中文。。。
0 请登录后投票
   发表时间:2009-11-20   最后修改:2009-11-20
我也发现这问题了,正在找解决方法,哪位找着了也请共享下啊,呵呵
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics