一个被弃用输出PDF,预览DOC格式的方法

来源:互联网 发布:游戏视频录制软件 编辑:程序博客网 时间:2024/05/29 00:33

预览是这么实现的:
把word文档另存为htm,然后改造成jsp,只要后台能传入正确的数据,那么页面显示的效果也就跟在word中显示一样了。

下载是这么实现的:
把页面上的HTML内容,经过工具类转化成字节流形式的PDF,然后向浏览器输出即可。

打印是这么实现的:
跟下载类似,只不过是向输出对象是打印机而已。

Controller代码如下:

public void downloadOld(HttpServletRequest req, HttpServletResponse resp) throws FileNotFoundException, IOException {    String id = getPara("id");    DecMessageFormMap decMessageFormMap = decImportDervice.findByFirst("id", id, DecMessageFormMap.class);    req.setAttribute("decMessageFormMap", decMessageFormMap);    req.setAttribute("decHeadFormMap", decImportDervice.findByFirst("id", decMessageFormMap.getStr("DecHeadId"), DecHeadFormMap.class));    req.setAttribute("decSignFormMap", decImportDervice.findByFirst("id", decMessageFormMap.getStr("DecSignId"), DecSignFormMap.class));    req.setAttribute("decFreeTxtFormMap", decImportDervice.findByFirst("id", decMessageFormMap.getStr("DecFreeTxtId"), DecFreeTxtFormMap.class));    req.setAttribute("decListFormMaps", decImportDervice.findByAttribute("DecMessageId", id, DecListFormMap.class));    req.setAttribute("decLicenseDocusFormMaps", decImportDervice.findByAttribute("DecMessageId", id, DecLicenseDocusFormMap.class));    req.setAttribute("decContainerFormMaps", decImportDervice.findByAttribute("DecMessageId", id, DecContainerFormMap.class));    req.setAttribute("ieFlag", getPara("ieFlag"));    new DownPDFUtils().downPDF(req, resp);}

DownPDFUtils:

public class DownPDFUtils {    public void downPDF(HttpServletRequest request,HttpServletResponse response) {        // 转发请求到jsp,返回解析之后的内容而不是输出到浏览器        String html = ServletUtils.forward(request, response, "/WEB-INF/jsp/dec/ieport/baoguandan.jsp");         byte[] pdf;        try {            pdf = PDFUtils.html2pdf(html);            response.reset();            response.setHeader("Content-Length", String.valueOf(pdf.length));            response.setContentType("application/pdf");            response.setHeader("Content-Disposition", "attachment;filename=" + new String(("报关单" + ".pdf").getBytes(), "iso-8859-1"));            response.setHeader("Connection", "keep-alive");            response.setHeader("Accept-Ranges", "none");            response.setHeader("X-Frame-Options", "DENY");            OutputStream out = response.getOutputStream();            out.write(pdf);            out.flush();        } catch (Exception e) {            e.printStackTrace();        }    }}

ServletUtils:

public class ServletUtils {    /**     * 此forward方法执行完毕之后不会输出内容到浏览器,而是把输出到字节流,最后以字符串的形式返回     * @param request     * @param response     * @param src     * @return     */    public static String forward(HttpServletRequest request, HttpServletResponse response, String src) {        try {            /*重新构造response,修改response中的输出流对象,使其输出到字节数组*/            final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();            final ServletOutputStream servletOuputStream = new ServletOutputStream() {                @Override                public void write(int b) throws IOException {                    byteArrayOutputStream.write(b);                }                @Override                public boolean isReady() {                    return false;                }                @Override                public void setWriteListener(WriteListener writeListener) {                }            };            final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, "UTF-8"));            response = new HttpServletResponseWrapper(response) {                @Override                public ServletOutputStream getOutputStream() {                    return servletOuputStream;                }                @Override                public PrintWriter getWriter() {                    return printWriter;                }            };            /*重新构造response,修改response中的输出流对象,使其输出到字节数组*/            // 执行forward操作            request.getRequestDispatcher(src).forward(request, response);            // 把字节流中的内容太转为字符串            return new String(byteArrayOutputStream.toByteArray(), "UTF-8");        } catch (Exception e) {            throw new RuntimeException(e);        }    }}

PDFUtils:

/** * pdf工具类 */public class PDFUtils {    /**     * 把html转换成pdf,以字节数组的形式返回pdf文件     *      * @param html     * @return pdf字节数组     * @throws IOException     * @throws DocumentException     * @throws CssResolverException     */    public static byte[] html2pdf(String html) throws IOException, DocumentException, CssResolverException {        Document document = new Document(PageSize.A4);        ByteArrayOutputStream os = new ByteArrayOutputStream();        PdfWriter writer = PdfWriter.getInstance(document, os);        document.open();        //处理字体样式        XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider() {            @Override            public Font getFont(String fontname, String encoding, float size, int style) {                return super.getFont(fontname == null ? "宋体" : fontname, encoding, size, style);            }        };        fontProvider.addFontSubstitute("lowagie", "garamond");        fontProvider.setUseUnicode(true);        // 使用我们的字体提供器,并将其设置为unicode字体样式        CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);        HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);        htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());        CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);        Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer)));        XMLWorker worker = new XMLWorker(pipeline, true);        XMLParser p = new XMLParser(worker);        p.parse(new InputStreamReader(new ByteArrayInputStream(html.getBytes("utf-8"))));        document.close();        return os.toByteArray();    }}

还有Java调用系统打印服务的代码,只是我已经删除了。=_=

当然,中间还考虑:表单数据比较多的时候是需要分页的;预览时生成临时文件,下载或者打印时都从临时文件取数据;后面弃用这些方法,是因为,
1:HTML转PDF的时候总会报错,这种方法只能转简单格式的HTML,稍微复杂点的都会失败。
2:打印是让用户在页面上操作,用户的机器进行打印,而不是服务器进行打印。
至于用itextpdf什么的,之前并没有用过,POI倒是有用过,之前用过定义Excel模板,然后代码中只需要向模板写数据的方法,避免了很多写排版,样式之类的代码。网上大概看了下itextpdf 的用法,似乎操作都是要定位到什么地方,输出什么格式的什么数据~~,我表示这不适合我这种懒人。
至于后面如何解决预览、下载、打印,在下一篇博客中介绍。

0 0