Как скачать PDF в JQuery AJAX вызова с использованием Java - PullRequest
1 голос
/ 04 ноября 2019

Я создал службу для загрузки файла PDF.

На моей стороне сервера (Java) PDF генерируется успешно. Но я не могу загрузить его на стороне пользовательского интерфейса (используя вызов Jquery Ajax).

Может кто-нибудь помочь мне с этим?

$(document).on('click', '.orderView', function(event){
    orderId = $(this).attr('data');
    $.ajax({
        type : 'GET',
        contentType : 'application/json',
        url : '../service/purchase/generateInventoryPurchasePdf/'+orderId,
        success : function(response) {
            console.log("Success");
        },
        error : function(response) {
            console.log("Error :" + response);
        }
    });

}); 

Java-код:

@RequestMapping(value = "/generateInventoryPurchasePdf/{purchaseId}", method = RequestMethod.GET)
public ResponseEntity<ByteArrayResource> generateInventoryPurchasePdf(HttpServletResponse response,@PathVariable("purchaseId") Long purchaseId) throws Exception {

PurchaseOrder purchaseOrder = null;
    purchaseOrder = purchaseService.findByPurchaseOrderId(purchaseId);

    // generate the PDF
    Map<Object,Object> pdfMap = new HashMap<>();
    pdfMap.put("purchaseOrder", purchaseOrder);
    pdfMap.put("purchaseOrderDetail", purchaseOrder.getPurchaseOrderDetail());
    pdfMap.put("vendorName", purchaseOrder.getInvVendor().getName());
    pdfMap.put("vendorAddrs", purchaseOrder.getInvVendor().getVenAddress().get(0));
    File file = util.generatePdf("email/purchasepdf", pdfMap);

    MediaType mediaType = MediaTypeUtils.getMediaTypeForFileName(this.servletContext, file.getName());
    System.out.println("fileName: " + file.getName());
    System.out.println("mediaType: " + mediaType);

    //Path path = Paths.get(file.getAbsolutePath() + "/" + file.getName());
    Path path = Paths.get(file.getAbsolutePath());
    byte[] data = Files.readAllBytes(path);
    ByteArrayResource resource = new ByteArrayResource(data);

    return ResponseEntity.ok()
            // Content-Disposition
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + path.getFileName().toString())
            // Content-Type
            .contentType(mediaType) //
            // Content-Lengh
            .contentLength(data.length) //
            .body(resource);
}

mediaUtil класс:

public class MediaTypeUtils {

    public static MediaType getMediaTypeForFileName(ServletContext servletContext, String fileName) {

        // application/pdf
        // application/xml
        // image/gif, ...
        String mineType = servletContext.getMimeType(fileName);
        try {
            MediaType mediaType = MediaType.parseMediaType(mineType);
            return mediaType;
        } catch (Exception e) {
            return MediaType.APPLICATION_OCTET_STREAM;
        }
    }
}

Создание PDFкод:

public File generatePdf(String templateName, Map<Object, Object> map) throws Exception {
    Assert.notNull(templateName, "The templateName can not be null");
    Context ctx = new Context();
    if (map != null) {
        Iterator<Entry<Object, Object>> itMap = map.entrySet().iterator();
        while (itMap.hasNext()) {
            Map.Entry<Object, Object> pair = itMap.next();
            ctx.setVariable(pair.getKey().toString(), pair.getValue());
        }
    }
    String processedHtml = templateEngine.process(templateName, ctx);
    FileOutputStream os = null;
    String fileName = "POLIST";
    try {
        final File outputFile = File.createTempFile(fileName, ".pdf",new File(servletContext.getRealPath("/")));

        outputFile.mkdir();
        os = new FileOutputStream(outputFile);
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocumentFromString(processedHtml);
        renderer.layout();
        renderer.createPDF(os, false);
        renderer.finishPDF();
        System.out.println("PDF created successfully");
        return outputFile;
    } finally {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) { 
            }
        }
    }
}

Я не получаю никакой ошибки, PDF успешно генерируется на стороне сервера. Но в интерфейсе пользователя не работает.

1 Ответ

1 голос
/ 04 ноября 2019

Загрузка файлов через AJAX не совсем логичная вещь. Когда вы делаете вызов AJAX, данные, возвращаемые с сервера, возвращаются в код JavaScript вашей страницы (в значении обратного вызова response), а не возвращаются в сам браузер, чтобы решить, что делать. Поэтому браузер не имеет возможности инициировать загрузку, потому что браузер не контролирует ответ напрямую - вместо этого ваш код JavaScript контролирует.

Как вы указали в своем комментарии под вопросом, есть обходные пути, которые вы можете использовать, но на самом деле лучший способ - просто использовать обычный не AJAX-запрос для загрузки

НапримерВы можете заменить свой код jQuery на что-то вроде

$(document).on('click', '.orderView', function(event){
    orderId = $(this).attr('data');
    window.open('../service/purchase/generateInventoryPurchasePdf/'+orderId);
});

. Это позволит загрузить документ с новой вкладки, не отходя от текущей страницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...