Saltar al contenido

Cómo dividir una página HTML en tamaño A4 en Angular 9

Te doy la bienvenida a nuestra página web, en este lugar vas a hallar la solucíon a lo que estás buscando.

Solución:

ingrese la descripción de la imagen aquí


En el archivo app.component.html:

En el archivo app.component.css:

.page 
    background: white;
    display: block;
    margin: 40px auto;
    box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5);
    box-sizing: border-box;

.page .content 
    overflow: auto;
    outline: 0;

En el archivo app.component.ts:

import  AfterViewChecked, Component  from '@angular/core';

@Component(
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
)
export class AppComponent implements AfterViewChecked 
  
  sizePage = 
    width: 21, //cm
    height: 29.7 //cm
  
  paddingPage = 
    top: 2, //cm
    right: 2, //cm
    bottom: 2, //cm
    left: 2 //cm
  
  pages = [
    
      htmlContent: null,
      full: false
    ,
  ]
  currentPage = 0;
  currentChar = null;

  runAfterViewChecked = false;
  
  clickPage(i) 
    this.currentPage = i;
  

  inputContent(char, i) 
    var element = document.getElementById('content-' + i)
    var heightContent = element.offsetHeight * 2.54 / 96; // Convert pixels to cm
    this.pages[i].htmlContent = element.innerHTML;
    console.log(this.pages);
    if (Number(heightContent.toFixed(1)) > this.sizePage.height)  
      this.currentChar = char;
      this.pages[i].full = true;
      if (!this.pages[i + 1]) 
        this.pages.push(
          htmlContent: null,
          full: false
        )
      
      this.currentPage = i + 1;
      this.runAfterViewChecked = true;
    
  

  ngAfterViewChecked() 
    document.getElementById('content-' + this.currentPage).focus();
    if (this.runAfterViewChecked) 
      if (this.currentChar) 
        var str = this.pages[this.currentPage-1].htmlContent;
        var indexLastCloseDiv = str.lastIndexOf("
"); var indexLastBr = str.lastIndexOf("
"); var lastChar = str[indexLastCloseDiv-1]; if (indexLastBr != -1 && (indexLastBr + 4) == indexLastCloseDiv) lastChar = ' '; if (indexLastCloseDiv != -1) str = str.slice(0, indexLastCloseDiv-1) + str.slice(indexLastCloseDiv); else str = str.slice(0, str.length - 1); this.pages[this.currentPage-1].htmlContent = str; if (this.pages[this.currentPage].htmlContent) this.pages[this.currentPage].htmlContent = lastChar + this.pages[this.currentPage].htmlContent; else this.pages[this.currentPage].htmlContent = lastChar; var element = null; for (let i = 0; i < this.pages.length; i++) element = document.getElementById('content-' + i); element.innerHTML = this.pages[i].htmlContent; this.runAfterViewChecked = false;

Enlace a Stackblitz

He aquí un ejemplo sencillo. Hay algunos errores, por favor dé sus sugerencias para un mayor desarrollo.

Algunas funciones como Retroceso, Eliminar, Escalar página, ... no se han procesado.

Se trata de dividir el contenido dado para que se ajuste al tamaño de página dado.

Podemos crear un componente que maneje la funcionalidad de división por nosotros. aquí hay una demostración de StackBlitz.

Y aquí hay una breve explicación.

Utilizar el ContentChildren decorador para observar el cambio de contenido. cada vez que cambie el contenido, ejecutaremos la lógica de creación de la página.

import 
  AfterContentInit,
  AfterViewInit,
  Component,
  ContentChildren,
  ElementRef,
  Input,
  OnInit,
  QueryList,
  ViewChild
 from "@angular/core";

@Component(
  selector: "app-paginated-view",
  templateUrl: "paginated-view.component.html",
  styleUrls: ["paginated-view.component.scss"]
)
export class PaginatedViewComponent implements AfterViewInit  "A4" = "A4";

  @ViewChild("paginatedView") paginatedView: ElementRef;

  @ViewChild("contentWrapper") contentWrapper: ElementRef;

  @ContentChildren("pageContent",  read: ElementRef ) elements: QueryList<
    ElementRef
  >;

  constructor() 

  ngAfterViewInit(): void 
    this.updatePages();

    // when ever childs updated call the updatePagesfunction
    this.elements.changes.subscribe(el => 
      this.updatePages();
    );
  

  updatePages(): void 
    // clear paginated view
    this.paginatedView.nativeElement.innerHTML = "";

    // get a new page and add it to the paginated view
    let page = this.getNewPage();
    this.paginatedView.nativeElement.appendChild(page);

    let lastEl: HTMLElement;
    // add content childrens to the page one by one
    this.elements.forEach(elRef => 
      const el = elRef.nativeElement;

      // if the content child height is larger than the size of the page
      // then do not add it to the page
      if (el.clientHeight > page.clientHeight) 
        return;
      
      // add the child to the page
      page.appendChild(el);

      // after adding the child if the page scroll hight becomes larger than the page height
      // then get a new page and append the child to the  new page
      if (page.scrollHeight > page.clientHeight) 
        page = this.getNewPage();
        this.paginatedView.nativeElement.appendChild(page);
        page.appendChild(el);
      
      lastEl = el;
    );

    //bring the element in to view port
    lastEl.scrollIntoView( behavior: "smooth", block: "nearest" );
  

  getNewPage(): HTMLDivElement 
    const page = document.createElement("div");
    page.classList.add("page");
    page.classList.add(this.pageSize);
    return page;
  

Podemos usar este componente en una aplicación como esta.


    

Hello World!!

This content will be displayed in an A4 size page

Tenemos que proporcionar la variable de plantilla #pageContent para que podamos seleccionarlos usando @ContentChildren en nuestro PaginatedViewComponent.

Tenga en cuenta que aquí estamos usando API nativas de dom para cambiar la estructura de dom. solo moverá el nodo dom de un lugar a otro, por lo que si tiene un detector de eventos agregado o tiene alguna propiedad que se vincule al contenido secundario, funcionará como está.

Editar:
También he actualizado su stackblitz https://stackblitz.com/edit/angular-ivy-zjf8rv

Si desea crear HTML A4 como la palabra de oficina A4, debe usar estos tamaños:

body
 width: 21cm ;
 height: 29.7cm;
 margin:30mm 45mm 30mm 45mm;

Si para ti ha sido de utilidad nuestro artículo, nos gustaría que lo compartas con más programadores y nos ayudes a extender nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *