print.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. interface PageSize {
  2. width: number
  3. height: number
  4. margin: number
  5. }
  6. const createIframe = () => {
  7. const iframe = document.createElement('iframe')
  8. iframe.style.width = '0'
  9. iframe.style.height = '0'
  10. iframe.style.position = 'absolute'
  11. iframe.style.right = '0'
  12. iframe.style.top = '0'
  13. iframe.style.border = '0'
  14. document.body.appendChild(iframe)
  15. return iframe
  16. }
  17. const writeContent = (doc: Document, printNode: HTMLElement, size: PageSize) => {
  18. const docType = '<!DOCTYPE html>'
  19. let style = ''
  20. const styleSheets = document.styleSheets
  21. if (styleSheets) {
  22. for (const styleSheet of styleSheets) {
  23. if (!styleSheet.cssRules) continue
  24. for (const rule of styleSheet.cssRules) {
  25. style += rule.cssText
  26. }
  27. }
  28. }
  29. const { width, height, margin } = size
  30. const head = `
  31. <head>
  32. <style type="text/css">
  33. ${style}
  34. html, body {
  35. height: auto;
  36. overflow: auto;
  37. }
  38. @media print {
  39. @page {
  40. size: ${width + 2 * margin}px ${height + 2 * margin}px;
  41. margin: ${margin}px;
  42. }
  43. }
  44. </style>
  45. </head>
  46. `
  47. const body = '<body>' + printNode.innerHTML + '</body>'
  48. doc.open()
  49. doc.write(`
  50. ${docType}
  51. <html>
  52. ${head}
  53. ${body}
  54. </html>
  55. `)
  56. doc.close()
  57. }
  58. export const print = (printNode: HTMLElement, size: PageSize) => {
  59. const iframe = createIframe()
  60. const iframeContentWindow = iframe.contentWindow
  61. if (!iframe.contentDocument || !iframeContentWindow) return
  62. writeContent(iframe.contentDocument, printNode, size)
  63. const handleLoadIframe = () => {
  64. iframeContentWindow.focus()
  65. iframeContentWindow.print()
  66. }
  67. const handleAfterprint = () => {
  68. iframe.removeEventListener('load', handleLoadIframe)
  69. iframeContentWindow.removeEventListener('afterprint', handleAfterprint)
  70. document.body.removeChild(iframe)
  71. }
  72. iframe.addEventListener('load', handleLoadIframe)
  73. iframeContentWindow.addEventListener('afterprint', handleAfterprint)
  74. }